本文目錄一覽:
怎樣用C語言編一個簡單的五子棋遊戲?
#include graphics.h
#include stdio.h
#include MATH.H
IMAGE* IMG;
IMAGE* IMG2;
IMAGE* IMG3;
IMAGE* whole;
bool mark = false;
int x = 0, y = 0;
int flag[15][15];
void show()
{
outtextxy(550, 100, “白方:”);
outtextxy(550, 150, ” 箭頭移動”);
outtextxy(550, 200, ” 回車鍵落子”);
outtextxy(550, 250, “黑方:”);
outtextxy(550, 300, ” ADWS移動”);
outtextxy(550, 350, ” 空格鍵落子”);
}
int success1(int dir1, int dir2)
{
int number = 0;
int temp_x = x, temp_y = y;
while (((temp_x / 35 + dir1) = 0 (temp_x / 35 + dir1) 15) ((temp_y / 35 + dir2) = 0 (temp_y / 35 + dir2) 15) (flag[(temp_x / 35 + dir1)][(temp_y / 35 + dir2)] == 1))
{
temp_x = temp_x + dir1 * 35;
temp_y = temp_y + dir2 * 35;
++number;
}
return number;
}
int success2(int dir1, int dir2)
{
int number = 0;
int temp_x = x, temp_y = y;
while (((temp_x / 35 + dir1) = 0 (temp_x / 35 + dir1) 15) ((temp_y / 35 + dir2) = 0 (temp_y / 35 + dir2) 15) (flag[(temp_x / 35 + dir1)][(temp_y / 35 + dir2)] == 2))
{
temp_x = temp_x + dir1 * 35;
temp_y = temp_y + dir2 * 35;
++number;
}
return number;
}
int success1()
{
int number = 0;
number = success1(0, -1) + success1(0, 1);//上下
if (number 4)
{
number = success1(-1, 0) + success1(1, 0);//左右
if (number 4)
{
number = success1(-1, -1) + success1(1, 1);//左上右下
if (number 4)
{
number = success1(-1, 1) + success1(1, -1);//左下右上
}
}
}
return number;
}
int success2()
{
int number = 0;
number = success2(0, -1) + success2(0, 1);//上下
if (number 4)
{
number = success2(-1, 0) + success2(1, 0);//左右
if (number 4)
{
number = success2(-1, -1) + success2(1, 1);//左上右下
if (number 4)
{
number = success2(-1, 1) + success2(1, -1);//左下右上
}
}
}
return number;
}
void control()
{
char key = 0;
while (key != 27)
{
Sleep(10);
if (kbhit())
{
key = getch();
switch (key)
{
case VK_LEFT:
if (mark)
break;
if (x 0)
x = x – 35;
break;
case ‘a’:
case ‘A’:
if (!mark)
break;
if (x 0)
x = x – 35;
break;
case VK_RIGHT:
if (mark)
break;
if (x 490)
x = x + 35;
break;
case ‘d’:
case ‘D’:
if (!mark)
break;
if (x 490)
x = x + 35;
break;
case VK_UP:
if (mark)
break;
if (y 0)
y = y – 35;
break;
case ‘w’:
case ‘W’:
if (!mark)
break;
if (y 0)
y = y – 35;
break;
case VK_DOWN:
if (mark)
break;
if (y 490)
y = y + 35;
break;
case ‘s’:
case ‘S’:
if (!mark)
break;
if (y 490)
y = y + 35;
break;
case VK_RETURN:
if (mark)
break;
if (flag[x / 35][y / 35] == 0)
{
putimage(whole, x + 6, y + 6, 31, 32, IMG2, 0, 0);
flag[x / 35][y / 35] = 1;
if (success1() = 4)
{
outtextxy(600, 50, “黑方 勝!”);
key = 27;
}
mark = true;
}
break;
case VK_SPACE:
if (!mark)
break;
if (flag[x / 35][y / 35] == 0)
{
putimage(whole, x + 6, y + 6, 31, 31, IMG3, 0, 0);
flag[x / 35][y / 35] = 2;
if (success2() = 4)
{
outtextxy(600, 50, “白方 勝!”);
key = 27;
}
mark = false;
}
break;
default:
break;
}
putimage(0, 0, whole);
putimage_transparent(NULL, IMG, x + 20, y + 20, 0x0, 0, 0, 20, 20);
}
}
}
void main()
{
setinitmode(0);
initgraph(800, 538);
SetWindowText(GetHWnd(), “五子棋20110327”);
setcolor(0xffffff);
setfont(36, 0, “楷體_GB2312”);
IMAGE* IMG1 = new IMAGE;
getimage(IMG1, “JPG”, MAKEINTRESOURCE(102));//棋盤
putimage(0, 0, IMG1);
IMG2 = new IMAGE;
getimage(IMG2, “JPG”, MAKEINTRESOURCE(103));//黑棋
IMG3 = new IMAGE;
getimage(IMG3, “JPG”, MAKEINTRESOURCE(104));//白棋
IMG = new IMAGE;
getimage(IMG, “GIF”, MAKEINTRESOURCE(101));//手形
whole = new IMAGE;
getimage(whole, 0, 0, 537, 537);
putimage_transparent(NULL, IMG, x + 20, y + 20, 0x0, 0, 0, 20, 20);
show();
control();
delete IMG1;
delete IMG2;
delete IMG3;
delete whole;
getch();
getch();
closegraph();
}
C語言五子棋算法
任何一種棋類遊戲其關鍵是對當前棋局是否有正確的評分,評分越準確則電腦的AI越高。五子棋遊戲也是如此,但在打分之前,我們先掃描
整個棋盤,把每個空位從八個方向上的棋型填入數組gStyle(2, 15, 15, 8, 2),其中第一個下標為1時表示黑棋,為2時表示白棋,第二和第三
個下標表示(x,y),第四個下標表示8個方向,最後一個下標為1時表示棋子數,為2時表示空格數,如:gStyle(1,2,2,1,1)=3表示與坐標(2,2)在第1個方向上相鄰的黑棋棋子數為3
gstyle(1,2,2,1,2)=4表示與坐標(2,2)在第1個方向上的最近的空格數為4
在定義方向時,也應該注意一定的技巧,表示兩個相反的方向的數應該差4,在程序中我是這樣定義的:
Const DIR_UP = 1
Const DIR_UPRIGHT = 2
Const DIR_RIGHT = 3
Const DIR_RIGHTDOWN = 4
Const DIR_DOWN = 5
Const DIR_DOWNLEFT = 6
Const DIR_LEFT = 7
Const DIR_LEFTUP = 8
這樣我們前四個方向可以通過加四得到另一個方向的值。如果你還是不太明白,請看下面的圖:
———
———
—oo—-
-ox*xx—
———
———
圖中的*點從標為(4,4),(打*的位置是空位),則:
gStyle(2,4,4,1,1)=1在(4,4)點相鄰的上方白棋數為1
gStyle(2,4,4,1,2)=2在(4,4)點的上方距上方白棋最近的空格數為2
gStyle(1,4,4,3,1)=2在(4,4)點相鄰的右方黑棋數為2
gStyle(1,4,4,3,2)=1在(4,4)點的右方距右方黑棋最近的空格數為3
…一旦把所有空點的棋型值填完,我們很容易地得出黑棋水平方向上點(4,4)的價值,由一個沖1(我把有界的棋稱為沖)和活2(兩邊無界的
棋稱為活)組成的。對於而白棋在垂直方向上點(4,4)的價值是一個活1,而在/方向也是活1所以,只要我們把該點的對於黑棋和白棋的價值算出
來,然後我們就取棋盤上各個空點的這兩個值的和的最大一點作為下棋的點。然而,對各種棋型應該取什麼值呢?我們可以先作如下假設:
Fn 表示先手n個棋子的活棋型,如:F4表示先手活四
Fn’表示先手n個棋子的沖棋型,如:F4’表示先手沖四
Ln 表示後手n個棋子的活棋型,如:L3表示後手活三
Ln’表示後手n個棋子的沖棋型,如:L3’表示後手沖三
.
.
.
根據在一行中的棋型分析,得到如下關係:
L1’=F1’L2’=F2’=L1F1L2F2L3’=F3’L4’F4’=F4
從這個關係包含了進攻和防守的關係(當然,這個關係是由我定的,你可以自己定義這些關係)。對這些關係再進一步細化,如在一個可下
棋的點,其四個方向上都有活三,也比不上一個沖四,所以我們可以又得到4*F3L4’這個關係,同樣,我們還可以得到其它的關係,如:4*F2L3、4*L3F3…,這些的關係由於你的定法和我的定法制可能不一樣,這樣計算機的AI也就不一樣,最後我們把分值最小的L1’值定為1,則我們就得
到了下面各種棋型的分值,由C語言表示為:
F[2][5]={{0,2,5,50,16000},{0,10,30,750,16000}};
L[2][5]={{0,1,5,50,3750},{0,10,30,150,4000}};
F數組表示先手,第一個下標為0時表示沖型,第二個下標表示棋子數,則F2’對應F[0][2]L數組表示後手,第一個下標為0時表示沖型,第二
個下標表示棋子數,則L2對應F[1][2]Ok,棋型的分值關係確定好了以後,我們把每一個可下點的四個方向的棋型值相加(包括先手和後手的分
值),最後選擇一個最大值,並把這一點作為計算機要下的點就OK了:)。後話:
1、得到最大值也許不止一個點,但在我的程序中只選擇第一個最大點,當然你可以用於個隨機數來決定
選擇那一個最大值點,也可以對這些最大值點再作進一步的分析。
2、在這個算法中我只考慮了周圍有棋子的點,而其它點我沒有考慮。
3、可以再更進一步,用這個算法來預測以後的幾步棋,再選擇預測值最好的一步,這樣電腦的AI就更高了
4、這個算法沒有考慮黑棋的禁手(雙3、雙四和多於五子的連棋)。因為在平時我下的五子棋是沒有這些
禁手的。
c語言基礎,求五子棋詳細代碼
/*一個月就想做五子棋,有點難啊,希望你能看懂,這是代碼*/
#include stdlib.h
#include stdio.h
#include conio.h
#include string.h
#define MAXIMUS 15 //定義棋盤大小
int p[MAXIMUS][MAXIMUS];//存儲對局信息
char buff[MAXIMUS*2+1][MAXIMUS*4+3];//輸出緩衝器
int Cx,Cy;//當前光標位置
int Now;//當前走子的玩家,1代表黑,2代表白
int wl,wp;//當前寫入緩衝器的列數和行數位置
char* showText;//在棋盤中央顯示的文字信息
int count;//回合數
char* Copy(char* strDest,const char* strSrc)//修改過的字符串複製函數,會忽略末端的\0
{
char* strDestCopy = strDest;
while (*strSrc!=’\0′)
{
*strDest++=*strSrc++;
}
return strDestCopy;
}
void Initialize()//初始化一個對局函數
{
int i,j;//循環變量
showText=””;//重置顯示信息
count=0;//回合數歸零
for(i=0;iMAXIMUS;i++)//重置對局數據
{
for(j=0;jMAXIMUS;j++)
{
p[i][j]=0;
}
}
Cx=Cy=MAXIMUS/2;//重置光標到中央
Now=1;//重置當前為黑方
}
char* getStyle(int i,int j)//獲得棋盤中指定坐標交點位置的字符,通過製表符拼成棋盤
{
if(p[i][j]==1)//1為黑子
return “●”;
else if(p[i][j]==2)//2為白子
return “○”;
else if(i==0j==0)//以下為邊緣棋盤樣式
return “┏”;
else if(i==MAXIMUS-1j==0)
return “┓”;
else if(i==MAXIMUS-1j==MAXIMUS-1)
return “┛”;
else if(i==0j==MAXIMUS-1)
return “┗”;
else if(i==0)
return “┠”;
else if(i==MAXIMUS-1)
return “┨”;
else if(j==0)
return “┯”;
else if(j==MAXIMUS-1)
return “┷”;
return “┼”;//中間的空位
}
char* getCurse(int i,int j)//獲得指定坐標交點位置左上格的樣式,通過製表符來模擬光標的顯示
{
if(i==Cx)
{
if(j==Cy)
return “┏”;
else if (j==Cy+1)
return “┗”;
}
else if(i==Cx+1)
{
if(j==Cy)
return “┓”;
else if (j==Cy+1)
return “┛”;
}
return “ ”;//如果不在光標附近則為空
}
void write(char* c)//向緩衝器寫入字符串
{
Copy(buff[wl]+wp,c);
wp+=strlen(c);
}
void ln()//緩衝器寫入位置提行
{
wl+=1;
wp=0;
}
void Display()//將緩衝器內容輸出到屏幕
{
int i,l=strlen(showText);//循環變量,中間文字信息的長度
int Offset=MAXIMUS*2+2-l/2;//算出中間文字信息居中顯示所在的橫坐標位置
if(Offset%2==1)//如果位置為奇數,則移動到偶數,避免混亂
{
Offset–;
}
Copy(buff[MAXIMUS]+Offset,showText);//講中間文字信息複製到緩衝器
if(l%2==1)//如果中間文字長度為半角奇數,則補上空格,避免混亂
{
*(buff[MAXIMUS]+Offset+l)=0x20;
}
system(“cls”);//清理屏幕,準備寫入
for(i=0;iMAXIMUS*2+1;i++)//循環寫入每一行
{
printf(“%s”,buff[i]);
if(iMAXIMUS*2)//寫入完每一行需要換行
printf(“\n”);
}
}
void Print()//將整個棋盤算出並儲存到緩衝器,然後調用Display函數顯示出來
{
int i,j;//循環變量
wl=0;
wp=0;
for(j=0;j=MAXIMUS;j++)//寫入出交點左上角的字符,因為需要打印棋盤右下角,所以很以橫縱各多一次循環
{
for(i=0;i=MAXIMUS;i++)
{
write(getCurse(i,j));//寫入左上角字符
if(j==0||j==MAXIMUS)//如果是棋上下盤邊緣則沒有連接的豎線,用空格填充位置
{
if(i!=MAXIMUS)
write(“ ”);
}
else//如果在棋盤中間則用豎線承接上下
{
if(i==0||i==MAXIMUS-1)//左右邊緣的豎線更粗
write(“┃”);
else if(i!=MAXIMUS)//中間的豎線
write(“│”);
}
}
if(j==MAXIMUS)//如果是最後一次循環,則只需要處理邊側字符,交點要少一排
{
break;
}
ln();//提行開始打印交點內容
write(“ ”);//用空位補齊位置
for(i=0;iMAXIMUS;i++)//按橫坐標循環正常的次數
{
write(getStyle(i,j));//寫入交點字符
if(i!=MAXIMUS-1)//如果不在最右側則補充一個橫線承接左右
{
if(j==0||j==MAXIMUS-1)
{
write(“━”);//上下邊緣的橫線更粗
}
else
{
write(“—”);//中間的橫線
}
}
}
ln();//寫完一行後提行
}
Display();//將緩衝器內容輸出到屏幕
}
int Put()//在當前光標位置走子,如果非空,則返回0表示失敗
{
if(p[Cx][Cy]==0)
{
p[Cx][Cy]=Now;//改變該位置數據
return 1;//返回1表示成功
}
else
{
return 0;
}
}
int Check()//勝負檢查,即判斷當前走子位置有沒有造成五連珠的情況
{
int w=1,x=1,y=1,z=1,i;//累計橫豎正斜反邪四個方向的連續相同棋子數目
for(i=1;i5;i++)//向下檢查
if(Cy+iMAXIMUSp[Cx][Cy+i]==Now)
w++;
else
break;
for(i=1;i5;i++)//向上檢查
if(Cy-i0p[Cx][Cy-i]==Now)
w++;
else
break;
if(w=5)//若果達到5個則判斷當前走子玩家為贏家
return Now;
for(i=1;i5;i++)//向右檢查
if(Cx+iMAXIMUSp[Cx+i][Cy]==Now)
x++;
else
break;
for(i=1;i5;i++)//向左檢查
if(Cx-i0p[Cx-i][Cy]==Now)
x++;
else
break;
if(x=5)//若果達到5個則判斷當前走子玩家為贏家
return Now;
for(i=1;i5;i++)//向右下檢查
if(Cx+iMAXIMUSCy+iMAXIMUSp[Cx+i][Cy+i]==Now)
y++;
else
break;
for(i=1;i5;i++)//向左上檢查
if(Cx-i0Cy-i0p[Cx-i][Cy-i]==Now)
y++;
else
break;
if(y=5)//若果達到5個則判斷當前走子玩家為贏家
return Now;
for(i=1;i5;i++)//向右上檢查
if(Cx+iMAXIMUSCy-i0p[Cx+i][Cy-i]==Now)
z++;
else
break;
for(i=1;i5;i++)//向左下檢查
if(Cx-i0Cy+iMAXIMUSp[Cx-i][Cy+i]==Now)
z++;
else
break;
if(z=5)//若果達到5個則判斷當前走子玩家為贏家
return Now;
return 0;//若沒有檢查到五連珠,則返回0表示還沒有玩家達成勝利
}
int RunGame()//進行整個對局,返回贏家信息(雖然有用上)
{
int input;//輸入變量
int victor;//贏家信息
Initialize();//初始化對局
while(1)//開始無限回合的死循環,直到出現勝利跳出
{
Print();//打印棋盤
input=getch();//等待鍵盤按下一個字符
if(input==27)//如果是ESC則退出程序
{
exit(0);
}
else if(input==0x20)//如果是空格則開始走子
{
if(Put())//如果走子成功則判斷勝負
{
victor=Check();
Now=3-Now;//輪換當前走子玩家
count++;
if(victor==1)//如果黑方達到勝利,顯示提示文字並等待一次按鍵,返回勝利信息
{
showText=”黑方獲得了勝利!”;
Print();
if(getch()==0xE0)
{
getch();
}
return Now;
}
else if(victor==2)//如果白方達到勝利,顯示提示文字並等待一次按鍵,返回勝利信息
{
showText=”白方獲得了勝利!”;
Display();
if(getch()==0xE0)
{
getch();
}
return Now;
}
else if(count==MAXIMUS*MAXIMUS)//如果回合數達到了棋盤總量,即棋盤充滿,即為平局
{
showText=”平局!”;
Display();
if(getch()==0xE0)
{
getch();
}
return 0;
}
}
}
else if(input==0xE0)//如果按下的是方向鍵,會填充兩次輸入,第一次為0xE0表示按下的是控制鍵
{
input=getch();//獲得第二次輸入信息
switch(input)//判斷方向鍵方向並移動光標位置
{
case 0x4B:
Cx–;
break;
case 0x48:
Cy–;
break;
case 0x4D:
Cx++;
break;
case 0x50:
Cy++;
break;
}
if(Cx0)//如果光標位置越界則移動到對側
Cx=MAXIMUS-1;
if(Cy0)
Cy=MAXIMUS-1;
if(CxMAXIMUS-1)
Cx=0;
if(CyMAXIMUS-1)
Cy=0;
}
}
}
int main()//主函數
{
system(“title 簡易五子棋 ——Etsnarl製作”);//設置標題
system(“mode con cols=63 lines=32”);//設置窗口大小
system(“color E0”);//設置顏色
while(1)//循環執行遊戲
{
RunGame();
}
return 0;
}
C語言程序設計 關於五子棋的
五子棋程序:
#includeiostream
using namespace std;
int Hsheng(char a[][15]);//判斷o子是否獲勝的函數
int Bsheng(char a[][15]);//判斷x子是否獲勝的函數
int he(char a[][15]);//判斷是否平局(也就是棋盤下滿了)的函數
void qipan(char a[15][15])//執行輸出棋盤命令
{ for(int i=0;i15;i++) //打印棋盤
{ for(int j=0;j15;j++)
couta[i][j];
coutendl; } }
int main()
{ char a[15][15]; int x,y;
for(int i=0;i15;i++)
for(int j=0;j15;j++)
a[i][j]=’ ‘; qipan(a);
while(1)//用循環語句執行o,x交替下子,這些while語句看起來似乎是個死循環~實際上都會經過break結束
{ int a1=1;
while(1)
{ for(;a1;)
{ cout”請輸入o子下的位置:”; //輸入o子的位置
cinxy; if(a[x][y]==’o’||a[x][y]==’x’)//判斷是否已有子
{cout”已有子請重下””,”;continue;}
else if(x=15||y=15){cout”輸入錯誤請重輸””,”;continue;}
else { a[x][y]=’o’; a1=0;}
} break;}
qipan(a);//下好o子後將棋盤顯示
if(Hsheng(a))//判斷o子是否已經獲勝
{ cout”o子獲勝”endl; break; }
while(1)//下x子
{ cout”請輸入x子下的位置:”;
cinxy;
if(a[x][y]==’o’||a[x][y]==’x’||x=15||y=15)
{ for( ; a[x][y]==’o’||a[x][y]==’x’; )
{ cout”已有子請重下”;
cout”請輸入x子下的位置:”;
cinxy;continue; }
for ( ; x=15||y=15||x; )
{ cout”輸入錯誤請重輸””,”; //判斷輸入棋子位置是否正確
cout”請輸入x子下的位置:”;
cinxy;continue ;}
a[x][y]=’x’;break; }
else
{ a[x][y]=’x’; break; } }
qipan(a);//再一次輸出棋盤
if(Bsheng(a))//判斷x子是否已經獲勝
{ cout”x子獲勝”endl; break; }
if(he(a))//判斷是否平局
{ cout”平局”endl; break; } }
return 0; }
int Hsheng(char a[][15])
{ int i,j;//判斷橫着的5個是否都相等
for(i=0;i15;i++)
for(j=0;j15;j++)
if(a[i][j]==’o’a[i][j+1]==’o’a[i][j+2]==’o’a[i][j+3]==’o’a[i][j+4]==’o’)
return 1;
for(j=0;j15;j++)//判斷豎著的5個是否都相等
for(i=0;i15;i++)
if(a[i][j]==’o’a[i+1][j]==’o’a[i+2][j]==’o’a[i+3][j]==’o’a[i+4][j]==’o’)
return 1;
for(i=0;i15;i++)//判斷左斜5個
for(j=0;j15;j++)
if(a[i][j]==’o’a[i+1][j+1]==’o’a[i+2][j+2]==’o’a[i+3][j+3]==’o’a[i+4][j+4]==’o’)
return 1;
for(i=0;i15;i++)//右斜5個
for(j=14;j3;j–)
if(a[i][j]==’H’a[i+1][j-1]==’o’a[i+2][j-2]==’o’a[i+3][j-3]==’o’a[i+4][j-4]==’o’)
return 1;
return 0; }
int Bsheng(char a[][15])//同o,只是改字符
{ int i,j;
for(i=0;i15;i++)
for(j=0;j15;j++)
if(a[i][j]==’x’a[i][j+1]==’x’a[i][j+2]==’x’a[i][j+3]==’x’a[i][j+4]==’x’)
return 1;
for(j=0;j15;j++)
for(i=0;i15;i++)
if(a[i][j]==’x’a[i+1][j]==’x’a[i+2][j]==’x’a[i+3][j]==’x’a[i+4][j]==’x’)
return 1;
for(i=0;i15;i++)
for(j=0;j15;j++)
if(a[i][j]==’x’a[i+1][j+1]==’x’a[i+2][j+2]==’x’a[i+3][j+3]==’x’a[i+4][j+4]==’x’)
return 1;
for(i=0;i15;i++)
for(j=14;j3;j–)
if(a[i][j]==’x’a[i+1][j-1]==’x’a[i+2][j-2]==’x’a[i+3][j-3]==’x’a[i+4][j-4]==’x’)
return 1;
return 0; }
int he(char a[][15])
{ for(int i=0;i15;i++)
for(int j=0;j15;j++)
{ if(a[i][j]==’ ‘)//當棋盤全部子都不是’ ‘時才能return 1,即棋盤已下滿
return 0;
}
return 1;
}
希望能幫到你!!
求五子棋的C語言程序,小學數學學習系統,簡單的學生成績管理程序
關於五子棋這個,我之前還自己做過。重裝系統後,程序沒了。說多了都是淚!
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/153175.html