無敵井字遊戲
無敵井字遊戲
http://delphi.ktop.com.tw/board.php?cid=168&fid=919&tid=20420
無敵井字遊戲
資料來源:http://neuron.et.ntust.edu.tw/homework/89/PL/89homework%231/A8902123/C++.htm
//---------------------------------------------------------------------------
// 程式名稱:無敵井字遊戲(目前為止)
// 開發環境:Borland C++ Builder 4.0 (Professional)
// 作業系統:Windows 95,98,2000,NT40
// 設 計 者:蘇坤明 (Allen or Su Kwan-Ming.)
// 伊 媚 兒:allen@xsun.com.tw
// 網站位址:http://www.xsun.com.tw
//
// 我是很支持OpenSource的作法,所以我寫的程式都會儘量公開原始程式
// 2000/8月份,我的第三套遊戲【超級比一比~絕色經典】預計上市
// 同時也會公開原始程式、工具軟體及出版此遊戲的製作說明書
// 歡迎對遊戲程式設計有興趣的玩家,踴躍上網訂購(預計8月初開放)(粉便宜哦!^-^)
// 請多多上我的網站,陸續會有很多好東西公開哦!!
// 願與大家一同成長! Allen. 2000/05/22.
//---------------------------------------------------------------------------
#include
#include
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const int CCBox[48]={// -|\/連線,其餘二格的座標位移
-2, 0,-1, 0,-1, 0, 1, 0, 1, 0, 2, 0, 0,-1, 0,-2, 0,-1, 0, 1, 0, 1, 0, 2,
1, 1, 2, 2,-1,-1, 1, 1,-1,-1,-2,-2, 1,-1, 2,-2,-1, 1, 1,-1,-1, 1,-2, 2};
//---------------------------------------------------------------------------
// 建構者
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//初始亂數
srand(GetTickCount());
while( int(GetTickCount()%5) != int(random(100)%5) );
}
//---------------------------------------------------------------------------
// 建立時
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
//建立9格按鈕
for(int y=0;y<3;y++)
for(int x=0;x<3;x++)
{
SB[y*3+x]=new TSpeedButton(Panel1);
SB[y*3+x]->Parent=Panel1;
SB[y*3+x]->Left=x*64+8;
SB[y*3+x]->Top =y*64+8;
SB[y*3+x]->Width =56;
SB[y*3+x]->Height=56;
SB[y*3+x]->forbidden=SBClick;
}
//初始分數
iHumanScore=0;
iComputerScore=0;
iSameScore=0;
//建立新局
SpeedButton1Click( SpeedButton1 );
}
//---------------------------------------------------------------------------
// 移除時
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
for(int i=0; i<9; i++) delete SB[i];
}
//---------------------------------------------------------------------------
// 玩家下棋動作
//---------------------------------------------------------------------------
void __fastcall TForm1::SBClick(TObject *Sender)
{
//本局已結束
if( iGameState==2 )
{
MessageBox(Handle,"本局已結束,請重開新局!","提示!",MB_OK|MB_ICONINFORMATION);
return;
}
//若不是空位
if( ((TSpeedButton *)Sender)->Caption!="" )
{
MessageBox(Handle,"此位不是空位!","提示!",MB_OK|MB_ICONINFORMATION);
return;
}
//空位則玩家可下
((TSpeedButton *)Sender)->Caption="O";
((TSpeedButton *)Sender)->Refresh();
if( CheckResult() ) return;//已有結果,電腦不必下,返回
ComputerAI();
if( CheckResult()==false ) //若未有結果,請玩家下
Panel2->Caption="請人類下";
}
//---------------------------------------------------------------------------
// 重開新局
//---------------------------------------------------------------------------
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
for(int i=0; i<9; i++) SB[i]->Caption="";
iGameState=random(100)%2;//以亂數決定誰先下
ShowInfo();
if( iGameState==1 )//電腦先下
{
ComputerAI();
Panel2->Caption="請人類下";
}
}
//---------------------------------------------------------------------------
// 電腦人工智慧
//---------------------------------------------------------------------------
void __fastcall TForm1::ComputerAI(void)
{
int i,j,x,y,max;
int ccvalue[9];
int sameidx[9],samecount;
AnsiString s;
//電腦思考中
Panel2->Caption="電腦思考中";
for(i=0;i<10;i++)
{
Panel2->Caption=Panel2->Caption+".";
Sleep(60);
Panel2->Refresh();
}
//特殊情形,依經驗法則來下
s="";
for(i=0;i<9;i++) s+=( SB[i]->Caption=="" ) ? AnsiString(".") : SB[i]->Caption;
if( s=="O...X...O" || s=="..O.X.O.." )
{
i=random(4)*2+1;
SB[i]->Caption="X";
SB[i]->Refresh();
return;
}
//權值歸0
for(i=0; i<9; i++) ccvalue[i]=0;
//計算各空位的權值
for(i=0; i<9; i++)
if( SB[i]->Caption=="" )//若是空位則計算
{
x=i%3;
y=i/3;
for(j=0; j<12; j++)
ccvalue[i]+=WhatValueIs(x+CCBox[j*4+0],y+CCBox[j*4+1],x+CCBox[j*4+2],y+CCBox[j*4+3]);
}
//找出最高權值
max=-1;
for(i=0; i<9; i++)
if( ccvalue[i]>max ) max=ccvalue[i];
//找出所有最高的權值
samecount=0;
for(i=0; i<9; i++)
if( ccvalue[i]==max )
{
sameidx[ samecount ]=i;//記錄位置
samecount++;//個數加1
}
//從最高權值位置,以亂數決定下於何處
i=random(samecount);
SB[ sameidx[i] ]->Caption="X";
SB[ sameidx[i] ]->Refresh();
}
//---------------------------------------------------------------------------
// 檢查並顯示結果,若為false代表結果未定
//---------------------------------------------------------------------------
bool __fastcall TForm1::CheckResult(void)
{
AnsiString tmp;//可連接的8條線所形成的字串
tmp[0]=SB[0]->Caption+SB[1]->Caption+SB[2]->Caption;
tmp[1]=SB[3]->Caption+SB[4]->Caption+SB[5]->Caption;
tmp[2]=SB[6]->Caption+SB[7]->Caption+SB->Caption;
tmp[3]=SB[0]->Caption+SB[3]->Caption+SB[6]->Caption;
tmp[4]=SB[1]->Caption+SB[4]->Caption+SB[7]->Caption;
tmp[5]=SB[2]->Caption+SB[5]->Caption+SB->Caption;
tmp[6]=SB[0]->Caption+SB[4]->Caption+SB->Caption;
tmp[7]=SB[2]->Caption+SB[4]->Caption+SB[6]->Caption;
//檢查電腦或人類是否勝利
for(int i=0; i<8; i++)
{
if(tmp[i]=="OOO")//人類勝利
{
FlashMsg("真厲害,您贏了","●真厲害,您贏了●");
iHumanScore++;
iGameState=2;
ShowInfo();
return true;
}
if(tmp[i]=="XXX")//電腦勝利
{
FlashMsg("電腦勝利!萬歲!","●電腦勝利!萬歲!●");
iComputerScore++;
iGameState=2;
ShowInfo();
return true;
}
}
//還有空位可下,表示還可玩,結果未定
for(int i=0; i<9; i++)
if( SB[i]->Caption=="" ) return false;
//若無空位,表示平手
FlashMsg("合局平手!","●合局平手!●");
iSameScore++;
iGameState=2;
ShowInfo();
return true;
}
//---------------------------------------------------------------------------
// 計算直線中,其餘2格的權值
//---------------------------------------------------------------------------
int __fastcall TForm1::WhatValueIs(int x1,int y1,int x2,int y2)
{
//超出棋盤外,無權值
if( x1<0 || y1<0 || x2<0 || y2<0 || x1>2 || y1>2 || x2>2 || y2>2 ) return 0;
//其餘2格,所形成的字串為何
AnsiString s=SB[y1*3+x1]->Caption + SB[y2*3+x2]->Caption;
//依重要性傳回權值
if( s=="XX" ) return 56; else
if( s=="OO" ) return 32; else
if( s=="X" ) return 4; else
if( s=="O" ) return 3; else
if( s=="" ) return 2;
else return 1;
}
//---------------------------------------------------------------------------
// 畫出遊戲資訊
//---------------------------------------------------------------------------
void __fastcall TForm1::ShowInfo(void)
{
LabelHuman->Caption=iHumanScore;
LabelComputer->Caption=iComputerScore;
LabelSame->Caption=iSameScore;
if( iGameState==0 ) {LabelWho->Caption="人類"; Panel2->Caption="請人類下";}
else if( iGameState==1 ) {LabelWho->Caption="電腦"; Panel2->Caption="";}
else {LabelWho->Caption="結束"; Panel2->Caption="本局結束";}
Refresh();
}
//---------------------------------------------------------------------------
// 閃爍Panel2訊息
//---------------------------------------------------------------------------
void __fastcall TForm1::FlashMsg(AnsiString s1,AnsiString s2)
{
for(int i=0; i<20; i++)
{
Panel2->Caption=(i&1)?s1:s2;
Panel2->Refresh();
Sleep(100);
}
ListBox1->Items->Add( "第 "+AnsiString(ListBox1->Items->Count+1)+" 次:"+s1 );
ListBox1->ItemIndex=ListBox1->Items->Count-1;
}
//---------------------------------------------------------------------------
// End
//---------------------------------------------------------------------------
--
◎龍貓資訊天地(bbs.mgt.ncu.edu.tw)
◎[brucetsao]From: 59-115-92-61.dynamic.hinet.net
推
05/12 14:17, , 1F
05/12 14:17, 1F
推
05/12 17:10, , 2F
05/12 17:10, 2F
推
05/12 20:05, , 3F
05/12 20:05, 3F
→
05/12 21:19, , 4F
05/12 21:19, 4F
Programming 近期熱門文章
PTT數位生活區 即時熱門文章