/////////////////////////////////////////////////////////////////////////////// // オセロ #include "el.h" #define MAIN_SCREEN 1 void MainScreen(void); DDOBJ bmpKoma, bmpBan; // スプライト int ban[8][8]; // 盤のデータ(-1:なし 0:自コマ 1:敵コマ) /////////////////////////////////////////////////////////////////////////////// // 指定した位置に駒を置く // 引数 x, y ... 置く駒の位置 // c ... 駒の種類(0:自コマ 1:敵コマ) // pf ... 実際に置く場合は true、チェックのみの場合は false // 戻値 駒が置ければ裏返った数、置けなければ 0 int PutKoma(int x, int y, int c, int pf = true) { int rx[8], ry[8], rn; int ret = 0; if (ban[y][x] != -1) return 0; for (int ay = -1; ay <= 1; ay++) { for (int ax = -1; ax <= 1; ax++) { int kx = x + ax; int ky = y + ay; rn = 0; for (;;) { if (kx < 0 || kx > 7 || ky < 0 || ky > 7) break; else if (ban[ky][kx] == -1) break; else if (ban[ky][kx] == c) { if (rn > 0) { if (pf) for (int i = 0; i < rn; i++) ban[ry[i]][rx[i]] = c; ret += rn; } break; } else { rx[rn] = kx; ry[rn] = ky; rn++; kx += ax; ky += ay; } } } } if (ret && pf) ban[y][x] = c; return ret; } /////////////////////////////////////////////////////////////////////////////// // コンピュータの思考 優先順位の高いところに駒を置く // 戻値 駒を置いたなら true、パスなら false bool Think() { // 優先順位 int pr[64] = { 0, 6, 2, 1, 1, 2, 6, 0, 6, 6, 5, 4, 4, 5, 6, 6, 2, 5, 2, 3, 3, 2, 5, 2, 1, 4, 3, 3, 3, 3, 4, 1, 1, 4, 3, 3, 3, 3, 4, 1, 2, 5, 2, 3, 3, 2, 5, 2, 6, 6, 5, 4, 4, 5, 6, 6, 0, 6, 2, 1, 1, 2, 6, 0, }; int rn[64] = {0}; int i, max = 0; for (int p = 0; p <= 6; p++) { for (i = 0; i < 64; i++) { if (pr[i] == p) { rn[i] = PutKoma(i % 8, i / 8, 1, false); if (rn[i] > max) max = rn[i]; } } if (max > 0) { do {i = rand() % 64;} while (rn[i] < max); PutKoma(i % 8, i / 8, 1); return true; } } return false; } /////////////////////////////////////////////////////////////////////////////// // メイン関数 int elMain("オセロ"); { elWindow(384, 384, FALSE); elLoop() { elSetScreen(MAIN_SCREEN, MainScreen()); } elExitMain(); } /////////////////////////////////////////////////////////////////////////////// // ウインドウ生成関数 void elCreate(void) { elDraw::Screen(384, 384); // ビットマップ読み込み bmpKoma = elDraw::LoadObject("koma.bmp"); bmpBan = elDraw::LoadObject("ban.bmp"); // 盤面初期化 for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { if (x == 3 && y == 3 || x == 4 && y == 4) ban[y][x] = 0; else if (x == 3 && y == 4 || x == 4 && y == 3) ban[y][x] = 1; else ban[y][x] = -1; } } elCallScreen(MAIN_SCREEN); } /////////////////////////////////////////////////////////////////////////////// // キーボード関数 void elKeyboard(void) { case VK_ESCAPE: { elDraw::Exit(); break; } elExitKeyboard(); } /////////////////////////////////////////////////////////////////////////////// // イベント関数 long elEvent(void) { elExitEvent(); } /////////////////////////////////////////////////////////////////////////////// // メイン画面 void MainScreen(void) { int x, y; static int pl = 0; // プレイヤー(0:プレイヤー 1:コンピュータ) static int passc = 0; // パスカウンタ static float pw = 0; // パス待ち時間秒数 elDraw::Clear(); if (pw > 0) { pw -= FrameTime; if (pw <= 0) pl = 1 - pl; } else if (pl == 0) { // プレイヤーの番 for (int i = 0; i < 64; i++) { if (PutKoma(i % 8, i / 8, 0, false)) break; } if (i >= 64) { pw = 1.0; passc++; } else if (MouseCL) { if (PutKoma(MousePX / 48, MousePY / 48, 0)) { pl = 1; passc = 0; } } } else { // コンピュータの番 if (Think()) { pl = 0; passc = 0; } else { pw = 1.0; passc++; } } // 表示 elDraw::Layer(0, 0, bmpBan, 0, 0, 384, 384); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { int b = ban[y][x]; if (b != -1) elDraw::Layer(x * 48, y * 48, bmpKoma, b * 48, 0, b * 48 + 48, 48); } } if (pw > 0) { if (pl == 0) SHOW(150, 186, " PLAYER PASS! "); else SHOW(145, 186, " COMPUTER PASS! "); } ShowCursor(TRUE); elDraw::Refresh(); // 全部の駒が置かれたかチェック int pc = 0, cc = 0; for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { if (ban[y][x] == 0) pc++; else if (ban[y][x] == 1) cc++; } } char* msg = NULL; if (cc == 0 || pc == 0 || pc + cc == 64 || passc >= 2) { if (pc > cc) msg = "あなたの勝ち"; else if (cc > pc) msg = "あなたの負け"; else msg = "引き分け"; } if (msg) { MESG("%d対%dで、%sです。", pc, cc, msg); elDraw::Exit(); } }