今天分享一波用C語言在Linux環境中編寫五子棋程式的代碼。
首先,實作五子棋,分為兩個部分:
需要的資料:
1、定義棋盤數組
2、定義變量用于記錄棋子位置
3、定義角色變量
業務邏輯:
是否需要對資料進行初始化
for(;;)
{
1、清理螢幕,顯示棋盤
2、落子
坐标要合法,原位置不能有棋子
3、檢查是否形成五子
4、切換角色
}
其中最重要的一環則是輸赢判斷,當判定一方獲勝時,結束遊戲,将數組置零,寫入檔案,然後結束遊戲。
判定輸赢的邏輯為,周遊一邊二維數組,找出被賦了非零值的數組項,判定他相鄰兩格内有無被賦予相同值的數組項,有則記錄加1,無則繼續周遊。其中相鄰記錄分為:橫(across)、豎(through),和斜(slant_r和slant_l)。周遊結束後這三項任一項資料大于等于1時,判定成功,遊戲結束。具體代碼稍顯過長但簡單易懂:
//判定是否獲勝
int across_w = 0,across_b = 0;
int through_w = 0,through_b=0;
int slant_r_w = 0,slant_r_b=0;
int slant_l_w = 0,slant_l_b=0;
for(int i = 0; i<15; i++)
{
for(int j =0; j<15;j++)
{
//判定白子獲勝
if(1 == arr[i][j])
{
(i>0 && i<15)&&( 1==arr[i][j-1]&&1 == arr[i][j+1]&&1 == arr[i][j+2]&&1 == arr[i][j-2])&& across_w++;
(j>0 && j<15)&&(1==arr[i-1][j]&&1 == arr[i+1][j]&&1 == arr[i+2][j]&&1 == arr[i-2][j]) && through_w++;
(i>0 && i<15 && j>0 && j<15)&&(1 == arr[i-1][j-1]&&1 == arr[i+1][j+1]&&1 == arr[i+2][j+2]&&1 == arr[i-2][j-2]) && slant_r_w++;
(i>0 && i<15 && j>0 && j<15)&&(1 == arr[i-1][j+1]&&1 == arr[i+1][j-1]&&1 == arr[i-2][j+2]&&1 == arr[i+2][j-2]) && slant_l_w++;
}
//判定黑子獲勝
if(2 == arr[i][j])
{
(i>0 && i<15)&&( 2==arr[i][j-1]&&2 == arr[i][j+1]&&2 == arr[i][j+2]&&2 == arr[i][j-2])&& across_b++;
(j>0 && j<15)&&(2==arr[i-1][j]&&2 == arr[i+1][j]&&2 == arr[i+2][j]&&2 == arr[i-2][j]) && through_b++;
(i>0 && i<15 && j>0 && j<15)&&(2 == arr[i-1][j-1]&&2 == arr[i+1][j+1]&&2 == arr[i+2][j+2]&&2 == arr[i-2][j-2]) && slant_r_b++;
(i>0 && i<15 && j>0 && j<15)&&(2 == arr[i-1][j+1]&&2 == arr[i+1][j-1]&&2 == arr[i-2][j+2]&&2 == arr[i+2][j-2]) && slant_l_b++;
}
}
}
printf("黑%d%d%d%d白%d%d%d%d",across_b,through_b,slant_l_b,slant_r_b,across_w,through_w,slant_r_w,slant_l_w);
if(across_b>=1 || through_b>=1 || slant_r_b>=1 || slant_l_b>1)
{
printf("黑子獲勝!遊戲結束!\n");
//exit_arr();
return 0;
}
if(across_w>=1 || through_w>=1 || slant_r_w>=1 || slant_l_w>=1)
{
printf("白子獲勝!遊戲結束!\n");
//exit_arr();
return 0;
}
棋盤顯示和光标移動部分:
void show_arr(void)
{
system("clear");
for(int i= 0; i<15; i++)
{
printf("-----------------------------------------------------------------------------\n");
for(int j= 0; j<15; j++)
{
if(arr[i][j])
{
if(2 == arr[i][j])
{
printf("| B");
}
if(1 == arr[i][j])
{
printf("| W");
}
}
else
{
printf("| ");
}
}
printf("|\n");
}
printf("-----------------------------------------------------------------------------\n");
for(;;)
{
printf("\33[%d;%dH",(x+1)*2,(y+1)*5);
switch(getch())
{
case 183: x>0 && x--; break;
case 184: x<14 && x++; break;
case 185: y<14 && y++; break;
case 186: y>0 && y--; break;
case 10 : return;
}
}
}
整個程式代碼:
#include <stdio.h>
#include <stdlib.h>
#include <getch.h>
#include <stdbool.h>
int x = 7, y = 7;
int step = 1;
int arr[15][15];
//1、顯示界面
void show_arr(void)
{
system("clear");
for(int i= 0; i<15; i++)
{
printf("-----------------------------------------------------------------------------\n");
for(int j= 0; j<15; j++)
{
if(arr[i][j])
{
if(2 == arr[i][j])
{
printf("| B");
}
if(1 == arr[i][j])
{
printf("| W");
}
}
else
{
printf("| ");
}
}
printf("|\n");
}
printf("-----------------------------------------------------------------------------\n");
for(;;)
{
printf("\33[%d;%dH",(x+1)*2,(y+1)*5);
switch(getch())
{
case 183: x>0 && x--; break;
case 184: x<14 && x++; break;
case 185: y<14 && y++; break;
case 186: y>0 && y--; break;
case 10 : return;
}
}
}
//判定黑棋還是白棋
void is_WB(void)
{
if(0 != arr[x][y])
{
printf("落子失敗!\n");
return;
}
//白子置為1
if(0 == step%2)
{
arr[x][y] = 1;
step ++;
}
//黑子置為2
else
{
arr[x][y] =2;
step++;
}
}
//加載資料
void start_arr(void)
{
FILE* frp = fopen("wuziqi.bin", "r");
if(NULL == frp)
{
printf("加載資料失敗!\n");
return ;
}
fread(arr,4,225,frp);
fclose(frp);
}
//儲存資料
void exit_arr(void)
{
FILE* fwp = fopen("wuziqi.bin","w");
if(NULL == fwp)
{
printf("儲存資料失敗!\n");
}
fwrite(arr,4,225,fwp);
fclose(fwp);
}
//主函數
int main()
{
//start_arr();
for(;;)
{
show_arr();
is_WB();
//判定是否獲勝
int across_w = 0,across_b = 0;
int through_w = 0,through_b=0;
int slant_r_w = 0,slant_r_b=0;
int slant_l_w = 0,slant_l_b=0;
for(int i = 0; i<15; i++)
{
for(int j =0; j<15;j++)
{
//判定白子獲勝
if(1 == arr[i][j])
{
(i>0 && i<15)&&( 1==arr[i][j-1]&&1 == arr[i][j+1]&&1 == arr[i][j+2]&&1 == arr[i][j-2])&& across_w++;
(j>0 && j<15)&&(1==arr[i-1][j]&&1 == arr[i+1][j]&&1 == arr[i+2][j]&&1 == arr[i-2][j]) && through_w++;
(i>0 && i<15 && j>0 && j<15)&&(1 == arr[i-1][j-1]&&1 == arr[i+1][j+1]&&1 == arr[i+2][j+2]&&1 == arr[i-2][j-2]) && slant_r_w++;
(i>0 && i<15 && j>0 && j<15)&&(1 == arr[i-1][j+1]&&1 == arr[i+1][j-1]&&1 == arr[i-2][j+2]&&1 == arr[i+2][j-2]) && slant_l_w++;
}
//判定黑子獲勝
if(2 == arr[i][j])
{
(i>0 && i<15)&&( 2==arr[i][j-1]&&2 == arr[i][j+1]&&2 == arr[i][j+2]&&2 == arr[i][j-2])&& across_b++;
(j>0 && j<15)&&(2==arr[i-1][j]&&2 == arr[i+1][j]&&2 == arr[i+2][j]&&2 == arr[i-2][j]) && through_b++;
(i>0 && i<15 && j>0 && j<15)&&(2 == arr[i-1][j-1]&&2 == arr[i+1][j+1]&&2 == arr[i+2][j+2]&&2 == arr[i-2][j-2]) && slant_r_b++;
(i>0 && i<15 && j>0 && j<15)&&(2 == arr[i-1][j+1]&&2 == arr[i+1][j-1]&&2 == arr[i-2][j+2]&&2 == arr[i+2][j-2]) && slant_l_b++;
}
}
}
printf("黑%d%d%d%d白%d%d%d%d",across_b,through_b,slant_l_b,slant_r_b,across_w,through_w,slant_r_w,slant_l_w);
if(across_b>=1 || through_b>=1 || slant_r_b>=1 || slant_l_b>1)
{
printf("黑子獲勝!遊戲結束!\n");
//exit_arr();
return 0;
}
if(across_w>=1 || through_w>=1 || slant_r_w>=1 || slant_l_w>=1)
{
printf("白子獲勝!遊戲結束!\n");
//exit_arr();
return 0;
}
}
exit_arr();
}