プログラミング及び演習 第15回 プログラミングプロジェクト (2015/07/24) 講義担当 情報連携統轄本部情報戦略室 大学院情報科学研究科メディア科学専攻 教授 森 健策 本日の講義・演習の内容 いよいよこれでプログラミング及び演習も最終回です みなさんのプログラミング能力は向上しましたか? 講義に対する感想、ならびに、この半期の自分の進 歩の程度などを回答に記入してください 2015/07/24 第2限出席テストに回答してください 内容 プログラミングプロジェクト課題の再確認 演習 デバッグの基本1 その1 「状態を知る」 プログラム内部の状態を表示する ブロック崩しの場合,各変数の内容を右側に一時的に表示 プロセスアタッチによるデバッグも有効です char text[1024]; sprintf( text, “Delay %d”, delay ); mvaddstr(y, x, text); 2015/07/17の講義資料を参考にしてください その2 「問題を切り分ける」 いったんすべての関数呼び出しをコメントアウトし、 順次コメントアウトを外す ある関数をテストする小さなプログラムを作る デバッグの基本2 その3 「ポインタには要注意」 Segmentation faultは発生しないが、不正なポイン タアクセスをしている場合が多々ある その4 「アルゴリズムの間違いも結構多い」 正しいと思っていたアルゴリズムが間違っている場 合はよくあるはず。自分の考えたアルゴリズムが間 違っていないか常に疑う 再掲 プログラミングプロジェクト課題 ブロック崩しゲームを作成 各自のアイデアを取り込み、より充実したゲーム を作成欲しい 構造体、線形リスト、双方向リスト、ファイルなど 講義で学んだことを最大限生かしてプログラム を作成する 余力があればネットワーク対戦型を作成 本課題提出は単位取得の必須条件 (通称: 夏休み課題) 再掲 仕様 (1/4) 画面構成 次ページ参照 画面サイズに合わせて縦・横に並ぶブロックの数を 変化させる、もしくは、画面サイズに合わせてブロッ クの大きさを変化させる 画面サイズを変更しても描画エリアが変化しないプ ログラムは認められない ブロックは#記号、ラケットは=記号、ボールは@記 号、枠は|,-記号で表示 右側に経過時間、Level, Score, High Score, High Scoreを出した人の名前を表示 再掲 画面構成 0 1 2 3 4 5 6 7 01234567890123456789012345678901234567890123456789012345678901234567890123456789 00*===================================================================* 1| | 2| |Time AAAAs 3| |Level AAAAA 4| ##### ##### ##### ##### ##### ##### ##### |Score AAAAA 5| |Ball AAAAA 6| ##### ##### ##### ##### ##### ##### ##### |HighS.AAAAA 7| |Name XXXXX 8| ##### ##### ##### ##### ##### ##### ##### | 9| | 10| | 1| | 2| | 3| | 4| | 5| | 6| | 7| @ | 8| | 9| | 20| | 1| | 2| ======== | 3| | 4| | 再掲 仕様 (2/4) ボールの動き 動く方向は45度斜め方向のみ 壁・ブロックに衝突した場合跳ね返る ボールがブロックに衝突するとボールが跳ね返り、 ブロックは消滅 Levelがあがるごとに動きを早める 3個のボールをLostするとゲームオーバー ラケット Levelがあがるごとに長さを短くする 再掲 仕様 (3/4) ブロック Scoreの計算 表示する数(縦の数x横の数)はプログラム内で変更 できるようにする 各ブロックの情報を構造体で表現すること 各自Scoreの計算方法を考える 経過時間 各ボールについて経過時間を表示する 再掲 仕様 (4/4) ゲーム開始時 過去上位5位のHigh Score List (得点、氏名)をファ イルから読み込む ゲーム終了時 上位5位以内であれば、名前の入力を促す 過去上位5位のHigh Score Listを表示 過去上位5位のHigh Score List (得点、氏名)をファ イルに書き出す 再掲 cursesライブラリとは 文字の画面への描画・キーボードからの入力を制御 可能となること 端末に依存しない方法 端末の違いはライブラリがterminfoファイルを参照することで 吸収 端末ウィンドウの操作 端末ウィンドウの操作出力(文字の描画など) 端末環境問い合わせ (画面の大きさ) カラー処理 cursesライブラリを使うには #include <curses.h> コンパイルオプションに-lncursesを追加 gcc -o prog prog.c -lncurses 再掲 curses walk-through (1/3) curses ライブラリルーチンの初期化 画面の初期化 エコーなしの「一度に 1 文字」入力をON cbreak(); noecho; 矢印キーをON initscr() を呼び出す keypad(stdscr,TRUE); キー入力を直ちにcheckするよう設定変更 timeout(0); 再掲 curses walk-through (2/3) curses ライブラリでの「ウィンドウ」 WINDOWS *と宣言される CRT 画面の全部分または一部分を表示する二次元 の文字配列 デフォルトのウィンドウとして端末画面と同一サイズ の stdscr が提供されている 他のウィンドウは newwin使って作成可 「ウィンドウ」使用終了時 endwin();を呼び出す 再掲 curses walk-through (3/2) デフォルトwindowへの文字の描画 int mvaddch(int y, int x, const chtype ch); int mvaddstr(int y, int x, const char *str); (x, y)に文字chを表示 y,xの順番で (x, y)に文字列strを表示 キーボードからの入力 int getch(); キーボードから一文字入力 キーを押せば直ちに入力される 再掲 curses walk-through (4/3) 特殊キーコード ← → ↑ ↓ KEY_LEFT KEY_RIGHT KEY_UP KEY_DOWN 画面サイズの取得 大域変数LINESに画面行数 大域変数COLSに画面横文字数 LINES, COLSは<curses.h>の中で定義 initscrを呼び出した時点で画面サイズの値が代入さ れる。 再掲 簡単なゲーム (1/4) #include <curses.h> void go(); int main(int argc, char **argv) { initscr(); /* curses */ noecho(); /* curses */ cbreak(); /* curses */ keypad(stdscr,TRUE);/* curses */ go(); endwin(); /* curses*/ return 0; } 再掲 簡単なゲーム (2/4) void go() { int locX, locY; int blocX, blocY; int blocDX, blocDY; int ch; int delay=0; int waitCount = 9000; locY = LINES - 5; locX = COLS/2; blocX = COLS/2; blocY = LINES/2; blocDX = 1; blocDY = -1; timeout(0); 再掲 簡単なゲーム (3/4) while((ch=getch())!='Q'){ mvaddstr(locY,locX," "); mvaddch(blocY,blocX,' '); if(delay%waitCount==0){ blocX += blocDX; blocY += blocDY; if(blocX<0){ blocX =0; blocDX = 1; } if(blocX>=COLS){ blocX =COLS-1; blocDX = -1; } if(blocY<0){ blocY =0; blocDY = 1; } if(blocY>=LINES-5&&(blocX>=locX)&&(blocX<=locX+4)){ blocY =LINES-6; blocDY = -1; beep(); } } delay++; 再掲 簡単なゲーム (4/4) switch(ch){ case KEY_LEFT: locX -=1; break; case KEY_RIGHT: locX +=1; break; case KEY_UP: waitCount-=100; break; case KEY_DOWN: waitCount+=100; break; default: break; } if(locX<0) locX=0; if(locX>=COLS) locX = COLS-1; mvaddstr(locY,locX,"====="); mvaddch(blocY,blocX,'@'); } } 色を出す,カーソルを消すには 以下のコードを挿入してください (太字の部分) int main(int argc, char **argv){ initscr(); start_color(); /* 色を使うための初期化 */ noecho(); cbreak(); init_pair(1, COLOR_WHITE, COLOR_RED); curs_set(0); /* カーソルを消す */ bkgd(COLOR_PAIR(1)); /* 背景を赤で消す */ attron(COLOR_PAIR(1)); /* 色セットを選択する */ keypad(stdscr,TRUE); go(); endwin(); return 0; } 再掲 時間の計測 #include <time.h> time_t time(time_t *t); 説明 time は紀元 (1970年1月1日00:00:00 UTC) からの 経過時間を秒単位で返す。も し t が NULL でな かったら返り値は t の指しているメモリにも格納され る。 返り値 成功した場合、紀元(the Epoch)からの経過秒数を 返す。 エ ラー の 場 合 は((time_t)-1) を返し、 errno を設定する。 再掲 使用例 - 経過時間を測る #include <time.h> main() { time_t start; time_t current; time(&start); while(1){ time(¤t); current -= start; printf( "Elapsed time = %d¥n", current); } }
© Copyright 2024 Paperzz