awkでライフゲーム(リアルタイム処理)
以前のブログの記事で、ライフゲームのアルゴリズムを紹介しました。
今回はawkでライフゲームをリアルタイムで動くプログラムを作りたいと思います。
BEGIN{ # [2]定数を定義 FIELD_WIDTH = 12; # [2-1]フィールドの幅を定義する FIELD_HEIGHT = 12 # [2-2]フィールドの高さを定義する FPS = 1000; # [2-3]1秒当たりの更新回数を定義する INTERVAL = 1000 / FPS; # [2-4]更新間隔(ミリ秒)を定義する # [3]変数を定義 field[0][0] = 0;field[0][1] = 1;field[0][2] = 0; field[1][0] = 0;field[1][1] = 0;field[1][2] = 1; field[2][0] = 1;field[2][1] = 1;field[2][2] = 1; lastClock = systime(); # [4-5-5]前回の経過時間を宣言する while(1){ newClock = systime(); # [4-5-7]現在の経過時間を宣言する # [4-5-8]前回の経過時間から、待機時間が経過していなければ if(newClock < lastClock + INTERVAL){ continue; # [4-5-9]待機時間に戻る } # [4-5-10]前回経過時間を現在の経過時間で更新する lastClock = newClock; DrawField(); # [4-5-11]フィールドを描画する関数を呼び出す # getch(); # [4-5-12]キーボード入力を待つ StepSimulation(); # [4-5-13]シミュレーションを進める } } # [4] 関数を宣言 function cls(){ printf("\033[H\033[J"); } function getch( cmd,k){ cmd="bash -c 'read -r -s -n 1 ke;echo $ke'" cmd | getline k; close(cmd) fflush() return k } # [4-1]フィールドを描画する関数 function DrawField(){ cls(); # [4-1-1]画面をクリアする # [4-1-2]フィールドのすべての行を反復する for(y = 0; y < FIELD_HEIGHT; y++){ # [4-1-3]フィールドのすべての列を反復する for(x = 0; x < FIELD_WIDTH; x++){ # [4-1-4]セルが生きていれば「■」を、死んでいれば「 」を描画する printf("%s",field[y][x] ? "■" : " "); } printf("\n"); # [4-1-5]1行描画するごとに改行する } } # [4-2]対象のセルと隣接する生きたセルの数を取得する関数 function GetLivingCellscount(_x,_y, x,y){ count = 0; # [4-2-1]生きているセルを数えるカンターを宣言 # [4-2-2]対象のセルの上下1マスを反復する for(y = _y - 1; y <= _y + 1; y++){ # [4-2-3]上下にループさせない場合は、行が範囲内かどうかを判定する # if((y < 0) || (y >= FIELD_HEIGHT)){ # continue; # [4-2-4]範囲外の行なのでスキップする # } # [4-2-5]上下にループしたY座標を宣言 roopedY = (FIELD_HEIGHT + y) % FIELD_HEIGHT; #print "y=",y,"roopedY=",roopedY,"x=",x,"roopedX=",roopedX,"count=",count; # [4-2-6]対象のセルの左右1マスを反復する for(x = _x + -1; x <= _x + 1; x++){ # [4-2-7]左右にループさせない場合は、列が範囲内かどうかを判定する # if((x < 0) || (x >= FIELD_WIDTH)){ # continue; # [4-2-8]範囲外の列なのでスキップする # } # [4-2-9]左右にループしたX座標を宣言する roopedX = (FIELD_WIDTH + x) % FIELD_WIDTH; # [4-2-10]対象の座標が、中心のセルと同じかどうかを判定する if((roopedX == _x) && (roopedY == _y)){ continue; # [4-2-11]対象の座標をスキップする } # [4-2-12]対象のセルが生きていれば1を、死んでいれば0を加算する count += field[roopedY][roopedX]; } } return count; # [4-2-13]生きているセルの数を返す } # [4-3]1ステップ分のシミュレーションを実行する関数 function StepSimulation(){ # [4-3-2]すべての行を反復する for(y = 0; y < FIELD_HEIGHT; y++){ # [4-3-3]すべての列を反復する for(x = 0; x < FIELD_WIDTH; x++){ # [4-3-4]対象のセルと隣接する、生きているセルの数を宣言 livingCellCount = GetLivingCellscount(x,y); # [4-3-5]隣接する生きたセルの数で分岐する if(livingCellCount <= 1){ # [4-3-5]1個なら # [4-3-6]対象のセルを死滅させる nextField[y][x] = 0; }else if(livingCellCount == 2){ # [4-3-7]2個なら # [4-3-8]現状維持 nextField[y][x] = field[y][x]; }else if(livingCellCount == 3){ # [4-3-9]3個なら # [4-3-10]対象のセルを誕生/生存させる nextField[y][x] = 1; }else{ # [4-3-11]4つ以上なら # [4-3-12]対象のセルを死滅させる nextField[y][x] = 0; } } } for(y = 0; y < FIELD_HEIGHT; y++){ for(x = 0; x < FIELD_WIDTH; x++){ field[y][x] = nextField[y][x]; } } }
awkで大きなプログラムを作る場合、変数をローカル変数になっているかどうか、きちんと確認する必要があります。
(私もこれにハマってしまい、バグを見つけるのに苦労しました)
utthi_fumi is awker!
awkでRPGゲーム
ゲームでプログラミングとなると、大抵はjavascriptで作ることが多いと思います。
キーボード操作やマウス操作が絡んできますからね。
awkでも、リアルタイムでキーボード操作ができれば、ゲームを作ることができます。
キーボード操作そのものはシェルスクリプトになります。
簡単なRPGゲーム(?)を作成してみました。
いきなり、ドラクエの最後のボスとの直接対決からスタートします。
wキーが上に移動、sキーが下に移動します。
ぜひ、最後の魔王を倒して、世界に平和をもたらしてください。
#! /usr/bin/gawk -f # rpg.awk function getch( cmd,k){ cmd="bash -c 'read -r -s -n 1 ke;echo $ke'" cmd | getline k; close(cmd) fflush() return k } function cls(){ printf("\033[H\033[J") } #[6-1]ゲームを初期化する関数を宣言する function Init(){ #[6-1-1]プレイヤーのステータスを初期化する characters[CHARACTER_PLAYER]["hp"] = monsters[MONSTER_PLAYER]["hp"]; characters[CHARACTER_PLAYER]["maxHp"] = monsters[MONSTER_PLAYER]["maxHp"]; characters[CHARACTER_PLAYER]["mp"] = monsters[MONSTER_PLAYER]["mp"]; characters[CHARACTER_PLAYER]["maxMp"] = monsters[MONSTER_PLAYER]["maxMp"]; characters[CHARACTER_PLAYER]["attack"] = monsters[MONSTER_PLAYER]["attack"]; characters[CHARACTER_PLAYER]["name"] = monsters[MONSTER_PLAYER]["name"]; } #[6-2]戦闘シーンの画面を描画する関数を宣言する function DrawBattleScreen(){ #[6-2-1]画面をクリアする cls(); # [6-2-2]プレイヤーの名前を表示する printf("%s\n",characters[CHARACTER_PLAYER]["name"]); # [6-2-3]プレイヤーのステータスを表示する printf("HP:%d/%d MP:%d/%d\n", characters[CHARACTER_PLAYER]["hp"], characters[CHARACTER_PLAYER]["maxHp"], characters[CHARACTER_PLAYER]["mp"], characters[CHARACTER_PLAYER]["maxMp"]); #[6-2-4]1行空ける printf("\n"); #[6-2-5]モンスターのアスキーアートを描画する printf("%s",characters[CHARACTER_MONSTER]["aa"]); #[6-2-6]モンスターのHPを表示する printf("(HP:%d/%d)\n", characters[CHARACTER_MONSTER]["hp"], characters[CHARACTER_MONSTER]["maxHp"]); #[6-2-7]1行空ける printf("\n"); } #[6-3]コマンドを選択する関数を宣言する function SelectCommand(){ #[6-3-1]プレイヤーのコマンドを初期化する characters[CHARACTER_PLAYER][character_command] = 0; #character_command = 0; #[6-3-2]コマンドが決定するまでループする while(1){ #[6-3-3]戦闘画面を描画する関数を呼び出す DrawBattleScreen(); #[6-3-4]コマンドの一覧を表示する for(i = 0; i < COMMAND_MAX; i++){ #[6-3-5]選択中のコマンドなら if(i == characters[CHARACTER_PLAYER][character_command]){ #[6-3-6]カーソルを描画する printf(">"); }else{ #[6-3-7]選択中のコマンドでなければ printf(" "); } #[6-3-9]コマンドの名前を表示する printf("%s\n",commandNames[i]); } #[6-3-10]入力されたキーによって分岐する switch(getch()){ case "w": #[6-3-11]wキーが押されたら #[6-3-12]上のコマンドに切り替える characters[CHARACTER_PLAYER][character_command]--; #character_command--; break; case "s": #[6-3-13]sキーが押されたら #[6-3-14]下のコマンドに切り替える characters[CHARACTER_PLAYER][character_command]++ #character_command++; break; default:#[6-3-15]上記以外のキーが押されたら return; #[6-3-16]関数を抜ける } #[6-3-17]カーソルを上下にループさせる characters[CHARACTER_PLAYER][character_command] = (COMMAND_MAX + characters[CHARACTER_PLAYER][character_command]) % COMMAND_MAX; } } #[6-4]戦闘シーンの関数を宣言する function Battle(_monster){ #[6-4-1]モンスターのステータスを初期化する characters[CHARACTER_MONSTER]["hp"] = monsters[_monster]["hp"]; characters[CHARACTER_MONSTER]["maxHp"] = monsters[_monster]["maxHp"]; characters[CHARACTER_MONSTER]["mp"] = monsters[_monster]["mp"]; characters[CHARACTER_MONSTER]["maxMp"] = monsters[_monster]["maxMp"]; characters[CHARACTER_MONSTER]["name"] = monsters[_monster]["name"]; characters[CHARACTER_MONSTER]["attack"] = monsters[_monster]["attack"]; characters[CHARACTER_MONSTER]["aa"] = monsters[_monster]["aa"]; #[6-4-2]プレイヤーの攻撃対象をモンスターに設定する characters[CHARACTER_PLAYER]["target"] = CHARACTER_MONSTER; #[6-4-3]モンスターの攻撃対象をプレイヤーに設定する characters[CHARACTER_MONSTER]["target"] = CHARACTER_PLAYER; #[6-4-3]モンスターの攻撃対象をプレイヤーに設定する #[6-4-4]戦闘シーンの画面を描画する関数を呼び出す DrawBattleScreen(); #[6-4-5]戦闘シーンの最初のメッセージを表示する printf("%sがあらわれた!\n",characters[CHARACTER_MONSTER]["name"]); #[6-4-6]キーボード入力を待つ getch(); #[6-4-7]戦闘シーンが終了するまでループする while(1){ #[6-4-8]コマンドを選択する関数を呼び出す SelectCommand(); #[6-4-9]各キャラクターを反復する for(i = 0; i < CHARACTER_MAX; i++){ #[6-4-10]戦闘シーンの画面を描写する関数を呼び出す DrawBattleScreen(); switch(characters[i][character_command]){ case 0: #[6-4-12]戦う printf("%sのこうげき!\n",characters[i]["name"]); getch(); #[6-4-15]敵に与えるダメージを計算する damage = 1 + int(rand() * 1000) % characters[i]["attack"]; #[6-4-16]敵にダメージを与える characters[characters[i]["target"]]["hp"] -= damage; #[6-4-17]敵のHPが負の値になったかどうかを判定する if(characters[characters[i]["target"]]["hp"] < 0){ #[6-4-18]敵のHPを0にする characters[characters[i]["target"]]["hp"] = 0; } #[6-4-19]戦闘シーンの画面を再描画する関数を呼び出す DrawBattleScreen(); #[6-4-20:敵にダメージを与えたメッセージを表示する printf("%sに%dのダメージ!\n",\ characters[characters[i]["target"]]["name"],\ damage); #[6-4-21]キーボード入力を待つ getch(); break; case 1: #[6-4-22]回復 #[6-4-23]MPが足りるかどうかを判定する if(characters[i]["mp"] < SPELL_COST){ #[6-4-24]MPが足りないメッセージを表示する printf("MPがたりない!\n"); #[6-4-25]キーボード入力を待つ getch(); #[6-4-26]呪文を唱える処理を抜ける break; } #[6-4-27]MPを消費させる characters[i]["mp"] -= SPELL_COST; #[6-4-28]画面を再描画する DrawBattleScreen(); #[6-4-29]回復するメッセージを表示する printf("%sは回復することにした!\n",characters[i]["name"]); #[6-4-30]キーボード入力を待つ getch(); #[6-4-31]HPを回復させる characters[i]["hp"] = characters[i]["maxHp"]; #[6-4-32]戦闘シーンの画面を再描画する DrawBattleScreen(); #[6-4-33]HPが回復したメッセージを表示する printf("%sのきずがかいふくした!\n",characters[i]["name"]); #[6-4-34]キーボード入力を待つ getch(); break; case 2: #[6-4-35]逃げる #[6-4-36]逃げ出したメッセージを表示する printf("%sはにげだした!\n",characters[i]["name"]); #[6-4-37]キーボード入力を待つ getch(); #[6-4-38]戦闘処理を抜ける return; break; } #[6-4-39]攻撃対象を倒したかどうかを判定する if(characters[characters[i]["target"]]["hp"] <= 0){ #[6-4-40]攻撃対象によって処理を分岐させる switch(characters[i]["target"]){ #[6-4-41]プレイヤーなら case 0: #[6-4-42]プレイヤーが死んだメッセージを表示する printf("あなたはしにました"); break; #[6-4-43]モンスターなら case 1: #[6-4-44]モンスターのアスキーアートを何も表示しないよう書き換える characters[characters[i]["target"]]["aa"] = ""; #[6-4-45]戦闘シーンの画面を再描画する関数を呼び出す DrawBattleScreen(); #[6-4-46]モンスターを倒したメッセージを表示する printf("%sをたおした!\n",\ characters[characters[i]["target"]]["name"]); break; } #[6-4-47]キーボード入力を待つ getch(); #[6-4-48]戦闘シーンの関数を抜ける return; } } } } #[6-6]プログラムの実行開始点を宣言 BEGIN{ # [5]変数を定義 MONSTER_PLAYER = 0; #[3-1-1]プレイヤー MONSTER_SLIME = 1; #[3-1-2]スライム MONSTER_BOSS = 2; #[3-1-3]魔王 MONSTER_MAX = 3; #[3-1-4]モンスターの種類の数 monsters[MONSTER_PLAYER]["hp"] = 100; monsters[MONSTER_PLAYER]["maxHp"] = 100; monsters[MONSTER_PLAYER]["mp"] = 15; monsters[MONSTER_PLAYER]["maxMp"] = 15; monsters[MONSTER_PLAYER]["attack"] = 30; monsters[MONSTER_PLAYER]["name"] = "ゆうしゃ"; monsters[MONSTER_SLIME]["hp"] = 3; monsters[MONSTER_SLIME]["maxHp"] = 3; monsters[MONSTER_SLIME]["mp"] = 0; monsters[MONSTER_SLIME]["maxMp"] = 0; monsters[MONSTER_SLIME]["attack"] = 2; monsters[MONSTER_SLIME]["name"] = "スライム"; monsters[MONSTER_SLIME]["aa"] = "/・Д・\\n"\ "~~~~~~";#アスキーアート monsters[MONSTER_BOSS]["hp"] = 255; monsters[MONSTER_BOSS]["maxHp"] = 255; monsters[MONSTER_BOSS]["mp"] = 0; monsters[MONSTER_BOSS]["maxMp"] = 0; monsters[MONSTER_BOSS]["attack"] = 50; monsters[MONSTER_BOSS]["name"] = "まおう"; monsters[MONSTER_BOSS]["aa"] = " A@A\n"\ "~(▼皿▼)~"; CHARACTER_PLAYER = 0; #[3-2-1]プレイヤー CHARACTER_MONSTER = 1; #[3-2-2]モンスター CHARACTER_MAX = 2; #[3-2-3]キャラクターの種類 character_command = 0; COMMAND_MAX = 3; #コマンドの種類の数 # [5-3]コマンドの名前を宣言する commandNames[0] = "たたかう"; #[5-3-1] commandNames[1] = "かいふく"; #[5-3-2] commandNames[2] = "にげる"; #[5-3-3] SPELL_COST = 3; #呪文の消費MPを定義する #[6-6-1]乱数をシャッフルする srand(); # [6-6-2]ゲームを初期化する関数を呼び出す Init(); # [6-6-3]戦闘シーンの関数を呼び出す Battle(MONSTER_BOSS); # [6-6-4]キーボード入力を待つ getch(); }
私自身、awkでここまで大掛かりなプログラミングをしたのは初めてで、かなり苦労しました。
しかし、awkでもここまで出来ることが分かったのではないでしょうか?
utthi_fumi is game programmer!
ライフゲーム
碁盤の目の上に、いくつかの石(生命体)を適当に配置する。これらの生命体は、以下に述べる簡単なルールに従って生き続ける。
それを見て楽しむという単純なゲームである。
盤面では、どの場所も縦・横・斜めに8個の場所と隣り合っているが、もしある場所が空いていて、しかもその場所と隣り合うちょうど3個の場所に生命体が存在するならば、次の世代にはその空いた場所に新しい生命体が誕生する。
一方、すでに存在する生命体については、隣り合う場所に住む生命体が1個以下または4個以上になると、過疎または過密のため、次の世代には死んでしまう。
以下ソース
#include<stdio.h> #include<stdlib.h> #define N 22 /* 縦方向 */ #define M 78 /* 横方向 */ char a[N + 2][M + 2], b[N + 2][M + 2]; /* 盤 */ int main(void){ int i, j, g; a[N / 2][M / 2] = a[N / 2 - 1][M / 2] = a[N / 2 + 1][M / 2] = a[N / 2][M / 2 - 1] = a[N / 2 - 1][M / 2 + 1] = 1; /* 初期状態 */ for(g = 1; g <= 1000; g++){ printf("Generation %4d\n",g); /* 世代 */ for(i = 1; i <= N; i++){ for(j = 1; j <= M; j++){ if(a[i][j]){ printf("*"); b[i - 1][j - 1]++; b[i - 1][j]++; b[i - 1][j + 1]++; b[i ][j - 1]++; b[i ][j + 1]++; b[i + 1][j - 1]++; b[i + 1][j]++; b[i + 1][j + 1]++; }else{ printf("."); } } printf("\n"); } for(i = 0; i <= N + 1; i++){ for(j = 0; j <= M + 1; j++){ if(b[i][j] != 2){ a[i][j] = (b[i][j] == 3); } b[i][j] = 0; } } } return 0; }
実行はぜひ皆さんの方で試してみてほしい
値の交換
変数a,bの値を交換するには、
a = b;b = a; /* 駄目 */
では駄目である。余分な変数tempを使って
temp = a;a = b; b = temp;
とする。あるいはビットごとの排他的論理和を使って
b ^= a; a ^= b; b ^= a;
としてもよい。
#include<stdio.h> void swap(int *x, int *y){ int temp; temp = *x; *x = *y; *y = temp; } int main(void){ int a = 1, b = 2; printf("a = %d,b = %d\n",a,b); swap(&a, &b); printf("a = %d,b = %d\n",a,b); }
実行してみる
a = 1,b = 2 a = 2,b = 1
簿記3級仕訳問題80本ノック(その1)
10問ずつ掲載しております
末尾の答えを押すと、解答と解説が表示されます。
問題 1
土地100,000円を購入し、仲介手数料2,000円、登記料3,000円とともに小切手を振り出して支払った。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
土地 | 105,000 * | 当座預金 | 105,000 |
■ 土地を購入⇒土地(資産)の増加⇒借方
* 付随費用は固定資産の取得原価に含める
100,000円+2,000円+3,000円=105,000円
■ 小切手を振り出した⇒当座預金(資産)の減少⇒貸方
POINT !
固定資産を取得する際の付随費用には、仲介手数料、登記料、据付費、引取運賃などがあります。これらの付随費用は固定資産の取得原価に含めます。
問題 2
期首において、備品(取得原価1,000円、既償却額600円)を500円で売却し、代金は月末に受け取ることとした。なお、間接法により 記帳している。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
備品減価償却累計額 | 600 | 備品 | 1,000* |
未収入金 | 500 | 固定資産売却益 | 100 |
■ 備品を売却した⇒備品(資産)の減少⇒貸方
* 間接法により記帳⇒備品の取得原価1,000円を減らす
■ 間接法により記帳⇒備品減価償却累計額の減少⇒借方
■ 代金は月末に受け取る⇒未収入金(資産)の増加⇒借方
■ 貸借差額⇒貸方⇒固定資産売却益(収益)
帳簿価額400円(1,000円-600円)よりも高い価額(500円)で売れた⇒売却益
問題 3
得意先島根商会が倒産し、同社に対する売掛金10,000円(前期に発生)が貸し倒れた。なお、貸倒引当金残高が8,000円ある。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
貸倒引当金 | 8,000 | 売掛金 | 10,000 |
貸倒損失 | 2,000 |
■ 前期の売掛金の貸倒れ(前期の債権には貸倒引当金が設定されている)⇒貸倒引当金(負債)の減少⇒借方
■ 貸倒引当金を超える分⇒貸倒損失(費用)の発生⇒借方
POINT !
問題 4
現金の実際有高が帳簿残高より54,000円不足していたため、かねて現金過不足勘定で処理しておいたが、その原因を調査したところ、通信費124,000円が記入漏れであること、ならびに保険料の支払額225,000円を354,000円と誤記入していたことが判明した。なお、残 額については原因不明のため、雑損または雑益として処理することとした。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
通信費 | 124,000 | 現金過不足 | 54,000 |
雑損 | 59,000 *2 | 保険料 | 129,000*1 |
■ 通信費の未記帳⇒現金過不足の減少
■ 保険料の修正⇒現金過不足の増加
■ 現金過不足の雑損への振り替え⇒現金過不足の減少
*1 354,000円-225,000円=129,000円
*2 54,000円+129,000円-124,000円=59,000円
問題 5
大阪商事から商品1,000,000円を仕入れた。注文時に手付金500,000円を支払っており、差し引いた残額については約束手形を振り出して支払った。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
仕入 | 1,000,000 | 前払金 | 500,000 |
支払手形 | 500,000* |
■ 商品の引き取り⇒仕入(費用)の発生⇒借方
■ 手付金を差し引く⇒前払金(資産)の減少⇒貸方
■ 約束手形の振り出し⇒支払手形(負債)の増加⇒貸方
* 1,000,000円-500,000円=500,000円
問題 6
先月の従業員給料から差し引いた所得税の源泉徴収税額190,000円を、現金で納付した。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
所得税預り金 | 190,000 | 現金 | 190,000 |
■ 現金で納付⇒現金(資産)の減少⇒貸方
POINT !
源泉所得税の預り金を預り金勘定で処理することもあります。
問題 7
出張中の社員から、当座預金口座に10,000円が入金されたが、その内容は不明である。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
当座預金 | 10,000 | 仮受金 | 10,000 |
■ 入金の内容は不明⇒仮受金(負債)の増加⇒貸方
問題 8
松山商事は商品480,000円を売り上げ、代金を山下商事の商品券で受け取った。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
受取商品券 | 480,000 | 売上 | 480,000 |
■ 商品の売り上げ⇒売上(収益)の増加⇒貸方
■ 受取商品券の受け取り⇒受取商品券(資産)の増加⇒借方
問題 9 4月27日 会計係は小口現金係から次のような支払いの報告を受けたので、ただちに小切手を振り出して小口現金を補給した。 通信費4,000円、旅費交通費20,000円、消耗品費3,000円
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
通信費 | 4,000 | 当座預金 | 27,000 |
旅費交通費 | 20,000 | ||
消耗品費 | 3,000 |
■ ただちに小切手を振り出して補給⇒ 当座預金(資産)の減少⇒貸方
■ 支払いの報告
通信費(費用)の発生⇒借方
旅費交通費(費用)の発生⇒借方
消耗品費(費用)の発生⇒借方
問題 10 内容不明の仮受金300円は、津田沼商会から注文を受けた際の手付金の受取額100円と水道橋商事に対する掛け代金の回収額200円であ ることが判明した。
借方科目 | 金額 | 貸方科目 | 金額 |
---|---|---|---|
仮受金 | 300 | 前受金 | 100 |
売掛金 | 200 |
■ 仮受金(負債)の内容判明⇒仮受金(負債)の減少⇒借方
■ 手付金と判明⇒前受金(負債)の増加⇒貸方
■ 掛け代金の回収と判明⇒売掛金(資産)の減少⇒貸方
サインカーブ
以下ソース
html
<canvas id="graph" width="800" height="800"></canvas>
let ctx; window.addEventListener("load", (event) => { let canvas = document.getElementById("graph"); ctx = canvas.getContext("2d"); paint(); }); function drawLine(x0, y0, x1, y1) { ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(x1, y1); ctx.stroke(); } function paint() { ctx.fillStyle = "white"; ctx.fillRect(0, 0, 800, 800); ctx.strokeStyle = "blue"; ctx.lineWidth = 4; drawLine(0, 400, 800, 400); drawLine(400, 0, 400, 800); ctx.strokeStyle = "black"; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(0, 400); for (let theta = -Math.PI * 2; theta < Math.PI * 2; theta += 0.1) { let x = (400 * theta) / (Math.PI * 2) + 400; let y = Math.sin(theta) * -300 + 400; ctx.lineTo(x, y); } ctx.stroke(); }
サイン、コサインカーブ
中心角の移動に応じて、sin/cosカーブをアニメーションで描画してみました。
以下、ソース
Enjoy!!
utthi_fumi is JavaScript Programmer!