オセロ
Posted: 2009年2月09日(月) 18:11
今度はAIを組み入れてみました。ちょっと長いですが・・
void COsero2Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 描画用のデバイス コンテキスト SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // クライアントの矩形領域内の中央 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // アイコンを描画します。 dc.DrawIcon(x, y, m_hIcon); } else { if(InitFrag){ CDC *pDC=GetDC(); int x,y; CBrush gray_brush, black_brush, white_brush; white_brush.CreateStockObject(WHITE_BRUSH);//白色 gray_brush.CreateSolidBrush(RGB(200,200,200));//灰色 black_brush.CreateSolidBrush(RGB(0,0,0));//黒色 pDC->SelectObject(&gray_brush); for(x=0;x<MASU_NUM;x++){ for(y=0;y<MASU_NUM;y++){ pDC->Rectangle(x*MASU_SIZE,y*MASU_SIZE,(x+1)*MASU_SIZE,(y+1)*MASU_SIZE); if(m_Board[x][y]==0)continue; else if(m_Board[x][y]==BLACK_STONE)pDC->SelectObject(&black_brush); else if(m_Board[x][y]==WHITE_STONE)pDC->SelectObject(&white_brush); pDC->Ellipse(x*MASU_SIZE+3, y*MASU_SIZE+3,(x+1)*MASU_SIZE-3,(y+1)*MASU_SIZE-3); pDC->SelectObject(&gray_brush); } } ReleaseDC(pDC); } CDialog::OnPaint(); } } void COsero2Dlg::OnButton1() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください MessageBox("ゲームを開始します"); InitFrag=TRUE; CurSor=TRUE; CDC *pDC=GetDC(); pDC->TextOut(450,100,"オセロゲーム"); CStatic *fr; fr=(CStatic *)GetDlgItem(IDC_STATIC1); fr->SetWindowText("黒が先手です"); shokika();//初期化関数 OnPaint();//描画関数 ReleaseDC(pDC); } void COsero2Dlg::shokika()//盤の初期化 { int x,y; for(x=0;x<MASU_NUM;x++){ for(y=0;y<MASU_NUM;y++){ m_Board[x][y]=0; m_Board[3][3]=BLACK_STONE; m_Board[4][4]=BLACK_STONE; m_Board[3][4]=WHITE_STONE; m_Board[4][3]=WHITE_STONE; } } Frag=TRUE;//先手は黒 CButton *B; B=(CButton *)GetDlgItem(IDC_BUTTON1); B->EnableWindow(FALSE); countALL=0;//手数の初期化 } void COsero2Dlg::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください int x,y; x=point.x/MASU_SIZE;//(例) 0-50のどこをクリックしても0と認識されるようにする y=point.y/MASU_SIZE; CDC *pDC=GetDC(); if(Rule(x,y)){ Reverce( x,y ); PutStone(x,y);//交互に石を置く関数 countALL++; OnPaint(); CStatic *p; p=(CStatic *)GetDlgItem(IDC_STATIC1); p->SetWindowText("黒の番です"); ReleaseDC(pDC); End(); MessageBox("CPUが打ちます"); AI(); nothing(); } BOOL COsero2Dlg::Rule(int x, int y) { if(x>=MASU_NUM && y>=MASU_NUM )return(FALSE);//マス数を超えるような位置には置けない。 if(m_Board[x][y]==WHITE_STONE ||m_Board[x][y]==BLACK_STONE)return(FALSE);//既に石がおいてあるところには置けない。 if(Rule(x,y,1,0))return TRUE;//右 if(Rule(x,y,0,1))return TRUE;//下 if(Rule(x,y,1,1))return TRUE;//右下 if(Rule(x,y,-1,-1))return TRUE;//左下 if(Rule(x,y,0,-1))return TRUE;//上 if(Rule(x,y,-1,0))return TRUE;//下 if(Rule(x,y,1,-1))return TRUE;//右上 if(Rule(x,y,-1,1))return TRUE;//左上 return FALSE; } void COsero2Dlg::PutStone(int x, int y)//交互に打つようにする { if(Frag==TRUE) m_Board[x][y]=BLACK_STONE; else m_Board[x][y]=WHITE_STONE; Frag=!Frag; } BOOL COsero2Dlg::Rule(int x, int y, int v_x, int v_y) { int put_stone; if(Frag==FALSE) put_stone=WHITE_STONE; else put_stone=BLACK_STONE; x+=v_x;// y+=v_y; if(m_Board[x][y]==0)return(FALSE);// if(m_Board[x][y]==put_stone)return(FALSE); x+=v_x; y+=v_y; while(x>=0 &&x<MASU_NUM && y>=0&& y<MASU_NUM){ if(m_Board[x][y]==0)return(FALSE); if(m_Board[x][y]==put_stone)return(TRUE); x+=v_x; y+=v_y; } return FALSE; } void COsero2Dlg::Reverce(int x, int y) { if(Rule(x,y,1,1)){ Reverce(x,y,1,1); } if(Rule(x,y,-1,-1)){ Reverce(x,y,-1,-1); } if(Rule(x,y,1,0)){ Reverce(x,y,1,0); } if(Rule(x,y,0,1)){ Reverce(x,y,0,1); } if(Rule(x,y,-1,0)){ Reverce(x,y,-1,0); } if(Rule(x,y,0,-1)){ Reverce(x,y,0,-1); } if(Rule(x,y,1,-1)){ Reverce(x,y,1,-1); } if(Rule(x,y,-1,1)){ Reverce(x,y,-1,1); } } void COsero2Dlg::Reverce(int x, int y, int v_x, int v_y) { int put_stone; if(Frag==FALSE) put_stone=WHITE_STONE; else put_stone=BLACK_STONE; while(m_Board[x+=v_x][y+=v_y]!=put_stone) m_Board[x][y]=put_stone; }