C語言實現 三子棋小遊戲(詳細+文尾附全程式碼)
文章目錄
宣告
我寫的可能有點複雜,如果想直接看程式碼,可直接跳轉到完整的程式碼流程部分,將其拼起來即可!
多檔案
在開始講三子棋之前呢,先說說多檔案吧。我們平常寫程式碼的時候,如果程式比較大,那麼直接包含在一個檔案中就會顯得比較亂,並且不容易維護,這個時候就需要用到多檔案。使用多檔案的時候可以將整個程式拆分開來,比方說分為標頭檔案、函式檔案、測試檔案。當然如果有需要的話,還可以繼續細分。
三子棋遊戲實現講解
test.c
要實現三子棋遊戲,首先要一個可以用來測試我們的程式碼的主函式部分 。我們玩遊戲通常都會有選擇,所以我們就可以在主函式這裡提供一個選擇的權力:玩還是退出,遊戲嘛,當然是玩完一盤又一盤的所以可以通過迴圈來實現!
//測試三子棋遊戲
#include "game.h"
void menu()
{
printf("**********************\n" );
printf("****1.play 0.exit***\n");
printf("**********************\n");
}
void test()
{
int num;
srand((size_t)time(NULL));
do
{
menu();
printf("請輸入你的選擇:>");
scanf("%d", &num);
switch (num)
{
case 1:
game();
break;
case 0:
printf ("退出遊戲\n");
break;
default:
printf("選擇有誤,請重新選擇:");
break;
}
} while (num);
}
int main()
{
test();
return 0;
}
game.h
這是標頭檔案的程式碼
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#define ROW 3 //行數
#define COL 3 //列數
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
//宣告
void INITBUF(char buf[ROW][COL], int row, int col);
void DisplayBuf(char buf[ROW][COL], int row, int col);
void PlayerMova(char buf[ROW][COL], int row, int col);
void ComputerMove(char buf[ROW][COL], int row, int col);
//告訴我們四種遊戲狀態
//玩家贏-'*'
//電腦贏-'# '
//平局-'P'
//繼續-'C'
char whowin(char buf[ROW][COL], int row, int col);
三子棋是三行三列,所以我們設定全域性變數方便使用,這裡的’*’,’#’是為了區別雙方對弈的棋子,大家也可以用其他替換,方便觀看即可!首先我們初始化棋盤資訊(INITBUF(buf, ROW, COL)),然後我們打印出棋盤(DisplayBuf(buf, ROW, COL))隨便後我們便開始玩家下棋(PlayerMova(buf, ROW, COL)),和電腦下棋(ComputerMove(buf, ROW, COL)),每下一次棋列印棋盤。最後判斷輸贏(whowin(char buf[ROW][COL], int row, int col))
game.c
實現三子棋每一個步驟的函式程式碼
有點長,所以我分成一個個的發,這樣更直觀
INITBUF()
初始化棋盤,初始化為空格
void INITBUF(char buf[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
buf[i][j] = ' ';
}
}
}
DisplayBuf()
列印棋盤
void DisplayBuf(char buf[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", buf[i][j]);
if (j < col - 1)
{
printf("|");
}
}
puts("");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
puts("");
}
}
}
PlayerMova()
玩家下棋
void PlayerMova(char buf[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走 >\n");
while (1)
{
printf("請輸入座標(row col):");
scanf("%d%d", &x, &y);
//判斷座標是否在有效範圍
//不是人人都懂陣列的用法,所以要確保座標的合法
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//不是人人都懂陣列的用法,所以要確保座標的合法
if (buf[x - 1][y - 1] == ' ')
{
buf[x - 1][y - 1] = '*';
break;
}
else
{
printf("此座標已佔用\n");
}
}
else
{
printf("輸入座標錯誤,請重新輸入!\n");
}
}
}
ComputerMove()
電腦下棋 採用隨機數的用法:引入標頭檔案 #include<time.h> ;產生隨機數:srand((size_t)time(NULL))在 test.c 函式裡引用
void ComputerMove(char buf[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("電腦走 >\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (buf[x][y] == ' ')
{
buf[x][y] = '#';
break;
}
}
}
whowin()
判斷輸贏
//返回1:表示棋盤滿了
//返回0:表示棋盤沒滿
int pingju(char buf[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (buf[i][j] == ' ')
{
return 0;//沒滿
}
}
}
return 1;//滿了
}
char whowin(char buf[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
if (buf[i][0] == buf[i][1] && buf[i][1] == buf[i][2] && buf[i][1] != ' ')
{
return buf[i][1];
}
}
for (i = 0; i < col; i++)
{
if (buf[0][i] == buf[1][i] && buf[1][i] == buf[2][i] && buf[1][i] != ' ')
{
return buf[1][i];
}
}
//對角線
if (buf[0][0] == buf[1][1] && buf[1][1] == buf[2][2] && buf[1][1] != ' ')
{
return buf[1][1];
}
if (buf[2][0] == buf[1][1] && buf[1][1] == buf[0][2] && buf[1][1] != ' ')
{
return buf[1][1];
}
//判斷是否平局
if (pingju(buf, ROW, COL) == 1)
{
return 'P';
}
return 'C';
}
game()
最後我們用**game()**將所有函式整合放到測試函式中,將其串起來
//整個遊戲的演算法實現
void game()
{
char ret = 0;
//陣列存放走出棋盤的資訊
char buf[ROW][COL] = { 0 };
//初始化棋盤
INITBUF(buf, ROW, COL);
//列印棋盤
DisplayBuf(buf, ROW, COL);
//下棋
while (1)
{
//玩家下棋
PlayerMova(buf, ROW, COL);
DisplayBuf(buf, ROW, COL);
ret = whowin(buf, ROW, COL);
if (ret != 'C')
{
break;
}
//電腦下棋
ComputerMove(buf, ROW, COL);
DisplayBuf(buf, ROW, COL);
ret = whowin(buf, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("你贏了,別得意了\n\n\n");
}
else if (ret == '#')
{
printf("你連人機都贏不了\n\n\n");
}
else
{
printf("和人機打成平手\n\n\n");
}
}
完整的程式碼流程就是
1.測試函式部分 test.c
//測試三子棋遊戲
#include "game.h"
void menu()
{
printf("**********************\n");
printf("****1.play 0.exit***\n");
printf("**********************\n");
}
//整個遊戲的演算法實現
void game()
{
char ret = 0;
//陣列存放走出棋盤的資訊
char buf[ROW][COL] = { 0 };
//初始化棋盤
INITBUF(buf, ROW, COL);
//列印棋盤
DisplayBuf(buf, ROW, COL);
//下棋
while (1)
{
//玩家下棋
PlayerMova(buf, ROW, COL);
DisplayBuf(buf, ROW, COL);
ret = whowin(buf, ROW, COL);
if (ret != 'C')
{
break;
}
//電腦下棋
ComputerMove(buf, ROW, COL);
DisplayBuf(buf, ROW, COL);
ret = whowin(buf, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("你贏了,別得意了\n\n\n");
}
else if (ret == '#')
{
printf("你連人機都贏不了\n\n\n");
}
else
{
printf("和人機打成平手\n\n\n");
}
}
void test()
{
int num;
srand((size_t)time(NULL));
do
{
menu();
printf("請輸入你的選擇:>");
scanf("%d", &num);
switch (num)
{
case 1:
game();
break;
case 0:
printf("退出遊戲\n");
break;
default:
printf("選擇有誤,請重新選擇:");
break;
}
} while (num);
}
int main()
{
test();
return 0;
}
標頭檔案部分 game.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#define ROW 3
#define COL 3
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
//宣告
void INITBUF(char buf[ROW][COL], int row, int col);
void DisplayBuf(char buf[ROW][COL], int row, int col);
void PlayerMova(char buf[ROW][COL], int row, int col);
void ComputerMove(char buf[ROW][COL], int row, int col);
//告訴我們四種遊戲狀態
//玩家贏-'*'
//電腦贏-'# '
//平局-'P'
//繼續-'C'
char whowin(char buf[ROW][COL], int row, int col);
3.三子棋函式實現部分 game.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void INITBUF(char buf[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
buf[i][j] = ' ';
}
}
}
void DisplayBuf(char buf[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", buf[i][j]);
if (j < col - 1)
{
printf("|");
}
}
puts("");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
puts("");
}
}
}
void PlayerMova(char buf[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走 >\n");
while (1)
{
printf("請輸入座標(row col):");
scanf("%d%d", &x, &y);
//判斷座標是否在有效範圍
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (buf[x - 1][y - 1] == ' ')
{
buf[x - 1][y - 1] = '*';
break;
}
else
{
printf("此座標已佔用\n");
}
}
else
{
printf("輸入座標錯誤,請重新輸入!\n");
}
}
}
void ComputerMove(char buf[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("電腦走 >\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (buf[x][y] == ' ')
{
buf[x][y] = '#';
break;
}
}
}
//返回1:表示棋盤滿了
//返回0:表示棋盤沒滿
int pingju(char buf[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (buf[i][j] == ' ')
{
return 0;//沒滿
}
}
}
return 1;//滿了
}
char whowin(char buf[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
if (buf[i][0] == buf[i][1] && buf[i][1] == buf[i][2] && buf[i][1] != ' ')
{
return buf[i][1];
}
}
for (i = 0; i < col; i++)
{
if (buf[0][i] == buf[1][i] && buf[1][i] == buf[2][i] && buf[1][i] != ' ')
{
return buf[1][i];
}
}
//對角線
if (buf[0][0] == buf[1][1] && buf[1][1] == buf[2][2] && buf[1][1] != ' ')
{
return buf[1][1];
}
if (buf[2][0] == buf[1][1] && buf[1][1] == buf[0][2] && buf[1][1] != ' ')
{
return buf[1][1];
}
//判斷是否平局
if (pingju(buf, ROW, COL) == 1)
{
return 'P';
}
return 'C';
}
謝謝觀看!!!