完成一個玩家與電腦對抗的九宮格的圈叉遊戲。
程式一開始,由玩家先下,使用的指令格式為「r,c」,r表示列數,c表示行數,例如「0,2」表示是下在第一列,第三行,玩家與電腦輪流下,直到九個格子都下滿,或是有一方連成一線。
玩家與電腦都不可以下在已經下過的格子。
每次電腦或玩家下完,你必須顯示棋盤的結果。
有人可以幫幫忙嗎???
作業作不出來阿
2007-03-26 08:30:03 · 2 個解答 · 發問者 ? 1 in 電腦與網際網路 ➔ 程式設計
// 檢查看是否有贏家,有的話,回傳贏家的 id,平手的話,回傳-1,還可以玩下去的話,回傳0
int Winner( char g[3][3])
{
int i;
// check col && row
for(i=0; i<3; i++)
{
if ( (g[i][0] == g[i][1] && g[i][1]== g[i][2]) && g[i][0] )
return g[i][0];
if ( (g[0][i] == g[1][i] && g[1][i]== g[2][i]) && g[0][i] )
return g[0][i];
}
// check diag
if( ((g[0][0] == g[1][1] && g[1][1]== g[2][2]) && g[1][1] ) ||
((g[2][0] == g[1][1] && g[1][1]== g[0][2]) && g[1][1] ) )
return g[1][1];
for(i=0; i<9; i++) if( !g[i/3][i%3] ) return 0;
return -1; // draw
}
// 把 g 印出來
void PrintGrid( char g[3][3])
{
int r, c;
printf("+---+---+---+\n");
for(r=0; r<3; r++)
{
for(c=0;c<3;c++) printf("| %d ", g[r][c]);
printf("|\n+---+---+---+\n");
}
}
// p是要下的步的id,r跟c是座標
// ScoreMove 會回傳一個 0.0~1.0的一個小數,數字愈大,代表在這下這一步對電腦愈有利
float ScoreMove( char g[3][3], int p, int r, int c)
{
int winningMove, i;
g[r][c] = p; // 先在r,c下假想的一步p
winningMove = Winner( g ); // 看有沒有贏家
if( winningMove ) // 有贏家了
{
g[r][c] = 0; // 先把剛下的那一步拿掉(因為是假想的)
switch( winningMove )
{
case -1: return 0.5f; // 平手,給 0.5分
case 1: return 0.0f; // PC輸,給 0.0分
case 2: return 1.0f; // PC贏,給 1.0分
}
}
else // 還沒贏家,所以還可以下
{
float score = 0.0f;
int cnt = 0;
// 檢查所有可以下的空格,看在那些空格下的話,分數為何,再平均所有的分數,當作這一格的分數
for(i=0; i<9; i++)
{
if( !g[i/3][i%3] ) // 空格,可以下
{
// 看這一格的分數為何 (要反轉 p,因為下一步是換另一方下的)
score += ScoreMove( g, p == 1 ? 2 : 1, i/3, i%3 );
cnt ++;
}
}
g[r][c] = 0; // 一樣,把我們最先下的山一步假想步拿掉
return score / cnt; // 回傳平均
}
}
// PCMove 會在 PC 認為最好的一步下一步棋,並印出棋盤
void PCMove( char g[3][3])
{
int bestR = 0;
int bestC = 0;
float bestScore = 0.0f;
int i;
// 檢查所有的空格
for( i=0; i<9; i++)
{
if( !g[i/3][i%3] )
{
// 看分數如何
float score = ScoreMove( g, 2, i/3, i%3 );
// 分數比最高分要高的話,就記錄這格
if( score > bestScore )
{
bestScore = score;
bestR = i/3;
bestC = i%3;
}
}
}
// 在最好的一步下
g[bestR][bestC] = 2;
printf("PC made move @ (%d, %d)\n", bestR, bestC);
PrintGrid(g);
}
int main()
{
char grid[3][3] = {0};
int r, c;
PrintGrid( grid );
while( !Winner( grid ) )
{
printf("Enter 2 number, (r c): ");
scanf("%d %d", &r, &c);
if( grid[r][c] )
{
printf("Invalid move\n");
continue;
}
grid[r][c] = 1;
PrintGrid( grid );
if( !Winner( grid ) )
PCMove( grid );
}
printf("Solved, winner is: %d\n", Winner(grid) );
getch();
}
===
重點在 ScoreMove 這個 function… 它會 recurse 所有可能的走法,計算出一個分數,愈高就代表那一步對PC來說愈好… 有這一個 function,其他都簡單… (就是不停的找最高分的一格下就好)
2007-03-27 06:58:04 · answer #1 · answered by Dave 7 · 0⤊ 0⤋
蠻好奇是否有人可以寫的
AI 我一點頭緒都沒有
2007-03-26 09:11:16 · answer #2 · answered by Anonymous · 0⤊ 0⤋