/////////////////////////////////////////////////////////////////////////////// // 7ならべ #include "el.h" #define MAIN_SCREEN 1 void MainScreen(void); struct { // 場に置いてあるカード int top; // 先頭 int end; // 末尾 } ba[4] = {6, 6, 6, 6, 6, 6, 6, 6}; struct { // プレイヤーデータ int num; // カード枚数 bool pass; // パスしたなら true int mark[12]; // 持っているカードのマーク int no[12]; // 持っているカードの数字 } pl[4]; DDOBJ bmpCard, bmpMark, bmpNumber; // スプライト /////////////////////////////////////////////////////////////////////////////// // メイン関数 int elMain("7ならべ"); { elWindow(640, 480, FALSE); elLoop() { elSetScreen(MAIN_SCREEN, MainScreen()); } elExitMain(); } /////////////////////////////////////////////////////////////////////////////// // ウインドウ生成関数 void elCreate(void) { elDraw::Screen(640,480); // ビットマップ読み込み bmpCard = elDraw::LoadObject("card.bmp"); bmpMark = elDraw::LoadObject("mark.bmp"); bmpNumber = elDraw::LoadObject("number.bmp"); // シャッフルしてカードを配る int mk, no, cn, pn; int ck[4][13] = {0}; // 配り終えたカードチェック用 for (mk = 0; mk < 4; mk++) ck[mk][6] = 1; // 7は配らない for (pn = 0; pn < 4; pn++) { for (cn = 0; cn < 12; cn++) { do {mk = rand() % 4; no = rand() % 13;} while (ck[mk][no] == 1); pl[pn].mark[cn] = mk; pl[pn].no[cn] = no; ck[mk][no] = 1; } pl[pn].num = 12; pl[pn].pass = false; } elCallScreen(MAIN_SCREEN); } /////////////////////////////////////////////////////////////////////////////// // キーボード関数 void elKeyboard(void) { case VK_ESCAPE: { elDraw::Exit(); break; } elExitKeyboard(); } /////////////////////////////////////////////////////////////////////////////// // イベント関数 long elEvent(void) { elExitEvent(); } /////////////////////////////////////////////////////////////////////////////// // カードを表示する関数 // 引数 x, y:表示する座標 no:数字(0 〜 12) mark:マーク(0 〜 3) void CardPrint(int x, int y, int no, int mark) { elDraw::Layer(x, y, bmpCard, 0, 0, 40, 64); elDraw::Layer(x + 6, y + 5, bmpMark, mark * 28, 0, mark * 28 + 28, 28); elDraw::Layer(x + 6, y + 33, bmpNumber, no * 28, 0, no * 28 + 28, 26); } /////////////////////////////////////////////////////////////////////////////// // 指定されたカードを場に出す関数 // 引数 pn:プレイヤー番号 cn:カード番号(0 〜 11) // 戻値 カードが出せれば true、出せなければ false // カードを出した場合、出したカードの分だけ前に詰める bool CardPut(int pn, int cn) { bool ret = true; int mk = pl[pn].mark[cn]; if (pl[pn].no[cn] == ba[mk].top - 1) ba[mk].top--; else if (pl[pn].no[cn] == ba[mk].end + 1) ba[mk].end++; else ret = false; if (ret) { for (int i = cn + 1; i < pl[pn].num; i++) { pl[pn].no[i - 1] = pl[pn].no[i]; pl[pn].mark[i - 1] = pl[pn].mark[i]; } pl[pn].num--; } return ret; } /////////////////////////////////////////////////////////////////////////////// // メイン画面 void MainScreen(void) { int i, cn; static int nowpl = 0; // 現在のプレイヤー(0:自分 1〜3:コンピュータ) static float wait = 0; // 待ち時間 char* pname[4] = {"You", "Com1", "Com2", "Com3"}; // プレイヤー名 elDraw::Clear(); if (nowpl == 0) { // 自分の順番のとき if (MouseCL) { int xs = (640 - pl[0].num * 40) / 2; if (MousePX >= xs && MousePX < xs + pl[0].num * 40 && MousePY >= 384 && MousePY < 384 + 64) { cn = (MousePX - xs) / 40; if (CardPut(0, cn)) { pl[0].pass = false; nowpl++; } } } else if (MouseCR) { pl[0].pass = true; nowpl++; } } else { // コンピュータの順番のとき wait += FrameTime; if (wait > 0.3) { wait = 0; int ck[12] = {0}; pl[nowpl].pass = true; for (int i = 0; i < pl[nowpl].num; i++) { do cn = rand() % pl[nowpl].num; while (ck[cn]); ck[cn] = 1; if (CardPut(nowpl, cn)) { pl[nowpl].pass = false; break; } } if (++nowpl >= 4) nowpl = 0; } } // 場のカード表示 for (int mk = 0; mk < 4; mk++) { for (int no = 0; no < 13; no++) { if (no >= ba[mk].top && no <= ba[mk].end) CardPrint(60 + no * 40, 64 + mk * 64, no, mk); } } // 手持ちのカード表示 for (cn = 0; cn < pl[0].num; cn++) { CardPrint((640 - pl[0].num * 40) / 2 + cn * 40, 384, pl[0].no[cn], pl[0].mark[cn]); } // プレイヤー情報表示 for (i = 0; i < 4; i++) { int x = 8 + i * 100; SHOW(x, 8, pname[i]); SHOW2(x, 24, "残り%d枚", pl[i].num); if (pl[i].pass) SHOW(x, 40, "Pass!"); } SHOW(8, 480 - 20, "左クリック:カードを出す 右クリック:パス"); ShowCursor(TRUE); elDraw::Refresh(); // 勝利者チェック for (i = 0; i < 4; i++) { if (pl[i].num <= 0) { MESG("%s Win!!", pname[i]); elDraw::Exit(); } } }