オセロ
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;
}