Download presentation
Presentation is loading. Please wait.
1
リバーシ 06a 藤田将義
2
スライド一覧 リバーシプログラムのメソッド vectorについて
3
メソッド一覧 メソッド名 説明 move Pointで指定された位置に石を打つ pass パスする undo 1つ前の手の状態に戻す
init ボードをゲーム開始直後の状態にする isGameOver ゲームが終了しているかどうか調べる getColor 指定した座標の石の色を調べる countDisc 指定された石の個数を返す getCurrentColor 現在の手番の色を返す getUpdate 直前の手で返された石が並んだvectorを返す getMovablePos 石の打てる座標が並んだvectorを返す getTurns 現在の手数を返す checkMobility 指定された座標に石を打てるか、またどの方向に石を裏返せるか判定
4
move { if(point.x <= 0 || point.x > BOARD_SIZE) return false;
if(point.y <= 0 || point.y > BOARD_SIZE) return false; if(MovableDir[Turns][point.x][point.y] == NONE) return false; flipDiscs(point); Turns++; CurrentColor = -CurrentColor; initMovable(); return true; } 石が打てるか判定 現在の手数、手番の色など更新
5
flipDiscs int x, y; Disc operation(point.x , point.y, CurrentColor); // 行った操作を表す石 int dir = MovableDir[Turns][point.x][point.y]; std::vector<Disc> update; RawBoard[point.x][point.y] = CurrentColor; update.push_back(operation); // 上 if(dir & UPPER) // 上に置ける { y = point.y; operation.x = point.x; while(RawBoard[point.x][--y] != CurrentColor) RawBoard[point.x][y] = CurrentColor; operation.y = y; }
6
flipDiscs ・ ・ // 石の数を更新 int discdiff = update.size();
・ ・ // 石の数を更新 int discdiff = update.size(); Discs[CurrentColor] += discdiff; Discs[-CurrentColor] -= discdiff -1; Discs[EMPTY]--; UpdateLog.push_back(update);
7
initMovable Disc disc(0, 0, CurrentColor); int dir;
MovablePos[Turns].clear(); for(int x=1; x<=BOARD_SIZE; x++) { disc.x = x; for(int y=1; y<=BOARD_SIZE; y++) disc.y = y; dir = checkMobility(disc); if(dir != NONE) // 置ける MovablePos[Turns].push_back(disc); } MovableDir[Turns][x][y] = dir;
8
checkMobility // 既に石があったら置けない
if(RawBoard[disc.x][disc.y] != EMPTY) return NONE; int x, y; unsigned dir = NONE; // 上 if(RawBoard[disc.x][disc.y-1] == -disc.color) { x = disc.x; y = disc.y-2; while(RawBoard[x][y] == -disc.color) { y--; } if(RawBoard[x][y] == disc.color) dir |= UPPER; }
9
ゲーム終了の判定 (isGameOver)
{ // 60手に達していたらゲーム終了 if(Turns == MAX_TURNS) return true; // 打てる手があるならゲーム終了ではない if(MovablePos[Turns].size() != 0) return false; //現在の手番と逆の色が打てるかどうか調べる Disc disc; disc.color = -CurrentColor; for(int x=1; x<=BOARD_SIZE; x++) disc.x = x; for(int y=1; y<=BOARD_SIZE; y++) disc.y = y; // 置ける箇所が1つでもあればゲーム終了ではない if(checkMobility(disc) != NONE) return false; } return true;
10
pass { // 打つ手があればパスできない
if(MovablePos[Turns].size() != 0) return false; // ゲームが終了しているなら、パスできない if(isGameOver()) return false; CurrentColor = -CurrentColor; // 空のupdateを挿入しておく UpdateLog.push_back(std::vector<Disc>()); initMovable(); return true; } UpdateLog.push_back(nullupdate);
11
undo { // ゲーム開始地点ならもう戻れない if(Turns == 0) return false;
CurrentColor = -CurrentColor; const std::vector<Disc> &update = UpdateLog.back(); // 前回がパスかどうかで場合分け // 前回はパス if(update.empty()) // MovablePos及びMovableDirを再構築 MovablePos[Turns].clear(); for(unsigned x=1; x<=BOARD_SIZE; x++) for(unsigned y=1; y<=BOARD_SIZE; y++) MovableDir[Turns][x][y] = NONE; } // 前回はパスでない else
12
undo Turns--; // 石を元に戻す RawBoard[x][y] = EMPTY;
for(unsigned i=1; i<update.size(); i++) { RawBoard[update[i].x][update[i].y] = -update[i].color; } // 石数の更新 unsigned discdiff = update.size(); Discs[CurrentColor] -= discdiff; Discs[-CurrentColor] += discdiff -1; Discs[EMPTY]--; // 不要になったupdateを1つ削除 UpdateLog.pop_back(); return true;
13
init { // 全マスを空きマスに設定 for(int x=1; x <= BOARD_SIZE; x++)
for(int y=1; y <= BOARD_SIZE; y++) RawBoard[x][y] = EMPTY; } // 壁の設定 for(int y=0; y < BOARD_SIZE + 2; y++) RawBoard[0][y] = WALL; RawBoard[BOARD_SIZE+1][y] = WALL; for(int x=0; x < BOARD_SIZE + 2; x++) RawBoard[x][0] = WALL; RawBoard[x][BOARD_SIZE+1] = WALL;
14
init // 初期配置 RawBoard[4][4] = WHITE; RawBoard[5][5] = WHITE;
RawBoard[4][5] = BLACK; RawBoard[5][4] = BLACK; // 石数の初期設定 Discs[BLACK] = 2; Discs[WHITE] = 2; Discs[EMPTY] = BOARD_SIZE*BOARD_SIZE - 4; // 手数は0から数える Turns = 0; // 先手は黒 CurrentColor = BLACK; // updateを全て消去 UpdateLog.clear(); initMovable(); }
15
情報を取得するメソッド unsigned countDisc(Color color) const {
return Discs[color]; } Color getColor(const Point& p) const return RawBoard[p.x][p.y]; const std::vector<Point>& getMovablePos() const return MovablePos[Turns]; 石の数を数える 指定された位置の色を返す 石を打てる座標が 並んだvectorを返す
16
情報を取得するメソッド 直前の手で打った石と 裏返した石が並んだ vectorを返す 現在の手番の色を返す 現在の手数を返す
std::vector<Disc> getUpdate() const { if(UpdateLog.empty()) return std::vector<Disc>(); else return UpdateLog.back(); } Color getCurrentColor() const return CurrentColor; unsigned getTurns() const return Turns; 直前の手で打った石と 裏返した石が並んだ vectorを返す 現在の手番の色を返す 現在の手数を返す
17
vectorについて サイズ可変な配列 1手目のupdate 2手目のupdate ・・・・ update 3手目のupdate
返された石の座標 ・・・・ 返された石の座標 n手目のupdate 新しく置いた石の座標
18
次回の予定 思考ルーチンについて 実際に動かせるようにしていく
19
参考文献 リバーシのアルゴリズム 著者 Seal Software
20
ご清聴ありがとうございました
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.