適合初學(xué)者練習(xí)的C語(yǔ)言實(shí)現(xiàn)三子棋小游戲
用簡(jiǎn)單的C語(yǔ)言來(lái)實(shí)現(xiàn)小時(shí)候玩的三子棋游戲,下面是人機(jī)對(duì)戰(zhàn),當(dāng)然這個(gè)代碼的電腦對(duì)手是人工智障而不是人工智能
一、寫代碼前明確下棋時(shí)的步驟與順序
- 1.創(chuàng)建一個(gè)3*3的棋盤.
- 2.將上面創(chuàng)建的棋盤中每個(gè)格初始化成' '狀態(tài).
- 3.打印出初始化完成的棋盤
- 4.玩家落子
- 5.電腦落子
- 6.判斷勝負(fù)
寫代碼之前梳理好大概的思路,先寫出初步的主函數(shù)
int main() {
char winner = ' ';
//1.創(chuàng)建一個(gè)棋盤,并初始化.
char board[MAX_ROW][MAX_COL] = { 0 };
//2.init函數(shù)將棋盤每個(gè)格子初始化成' '.
init(board);
while (1) {
//3.打印棋盤
printBoard(board);
//4.玩家落子
playerMove(board);
//5.判斷勝負(fù)
winner = checkWinner(board);
if (winner != ' ') {
//勝負(fù)已分
break;
}
//6.電腦落子
computerMove(board);
//7.判斷勝負(fù)
winner = checkWinner(board);
if (winner != ' ') {
//勝負(fù)已分
break;
}
}
在創(chuàng)建棋盤是char board[][]的[]中不要寫3,寫3在后面看代碼時(shí)不能明確分清3代表什么
因此建議定義宏
#define MAX_ROW 3 #define MAX_COL 3
這樣可以清楚的看出[]中的內(nèi)容代表什么,提高可讀性.
二 根據(jù)初步的主函數(shù)完成想要的代碼
1.寫一個(gè)函數(shù)來(lái)初始化棋盤
//將棋盤初始化成' '
void init(char board[MAX_ROW][MAX_COL]) {
for (int row = 0; row < MAX_ROW; row++) {
for(int col = 0; col < MAX_COL; col++) {
board[row][col] = ' ';
}
}
//設(shè)計(jì)隨機(jī)種子
srand((unsigned int) time(0));
}
2.打印棋盤
void printBoard(char board[MAX_ROW][MAX_COL]) {
system("cls");
for (int row = 0; row < MAX_ROW; row++) {
printf("+---+---+---+\n");
for (int col = 0; col < MAX_COL; col++) {
printf("| %c ", board[row][col]);
}
printf("|");
printf("\n");
}
printf("+---+---+---+\n");
}
system("cls")是讓每次打印棋盤前清除之前的棋盤這樣能讓界面清晰一些
(使用的是簡(jiǎn)單的C來(lái)完成程序所以打印的棋盤也比較簡(jiǎn)陋)
3.玩家落子
void playerMove(char board[MAX_ROW][MAX_COL]) {
printf("請(qǐng)玩家落子!");
while (1) {
printf("請(qǐng)輸入落子的位置(row col):");
int row = 0;
int col = 0;
scanf("%d %d", &row, &col);
//輸入后驗(yàn)證輸入內(nèi)容是否合法.
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) {
printf("輸入有誤.請(qǐng)重新輸入!\n");
continue;
}
if (board[row][col] != ' ') {
printf("當(dāng)前位置已有棋子,請(qǐng)重新輸入!\n");
continue;
}
board[row][col] = 'x';
break;
}
}
以輸入坐標(biāo)的方式來(lái)實(shí)現(xiàn)落子,并且要檢測(cè)玩家落子是否合理,以免輸入無(wú)效的坐標(biāo).
4.電腦落子
void computerMove(char board[MAX_ROW][MAX_COL]) {
printf("輪到電腦落子");
while (1) {
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (board[row][col] != ' ') {
continue;
}
board[row][col] = 'o';
break;
}
}
電腦落子采用隨機(jī)數(shù)的方式來(lái)進(jìn)行落子,因此需要設(shè)置隨機(jī)種子,將它寫在初始化棋盤函數(shù)內(nèi),每次初始化一次進(jìn)行一次隨機(jī)種子的設(shè)置
由于是隨機(jī)落子因此實(shí)現(xiàn)的不是人工智能而是人工智障.
5.判斷勝負(fù)
int checkWinner(char board[MAX_ROW][MAX_COL]) {
//檢查所有行
for (int row = 0; row < MAX_ROW; row++) {
if (board[row][0] != ' ' && board[row][0] == board[row][1] && board[row][0] == board[row][2]) {
return board[row][0];
}
}
//檢查所有列
for (int col = 0; col < MAX_COL; col++) {
if (board[0][col] != ' ' && board[0][col] == board[1][col] && board[0][col] == board[2][col]) {
return board[0][col];
}
}
//檢查對(duì)角線
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ') {
return board[0][0];
}
if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] != ' ') {
return board[0][2];
}
if (isFull(board)) {
return 'q';
}
return ' ';
}
檢查每行 每列 對(duì)角線是否有三個(gè)相同的棋子從而判斷勝負(fù).
int isFull(char board[MAX_ROW][MAX_COL]) {
for (int row = 0; row < MAX_ROW; row++) {
for (int col = 0; col < MAX_COL; col++) {
if (board[row][col] == ' ') {
//棋盤沒(méi)滿
return 0;
}
}
}
return 1;
}
檢查棋盤有沒(méi)有下滿(可能出現(xiàn)和棋)
這就實(shí)現(xiàn)一個(gè)簡(jiǎn)單的三子棋游戲
在主函數(shù)中玩家落子后應(yīng)也判斷一次勝負(fù),以免出現(xiàn)玩家勝利電腦再落子的情況.
三、三子棋實(shí)現(xiàn)代碼
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#define MAX_ROW 3
#define MAX_COL 3
//將棋盤初始化成' '
void init(char board[MAX_ROW][MAX_COL]) {
for (int row = 0; row < MAX_ROW; row++) {
for(int col = 0; col < MAX_COL; col++) {
board[row][col] = ' ';
}
}
//設(shè)計(jì)隨機(jī)種子
srand((unsigned int) time(0));
}
void printBoard(char board[MAX_ROW][MAX_COL]) {
system("cls");
for (int row = 0; row < MAX_ROW; row++) {
printf("+---+---+---+\n");
for (int col = 0; col < MAX_COL; col++) {
printf("| %c ", board[row][col]);
}
printf("|");
printf("\n");
}
printf("+---+---+---+\n");
}
void playerMove(char board[MAX_ROW][MAX_COL]) {
printf("請(qǐng)玩家落子!");
while (1) {
printf("請(qǐng)輸入落子的位置(row col):");
int row = 0;
int col = 0;
scanf("%d %d", &row, &col);
//輸入后驗(yàn)證輸入內(nèi)容是否合法.
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) {
printf("輸入有誤.請(qǐng)重新輸入!\n");
continue;
}
if (board[row][col] != ' ') {
printf("當(dāng)前位置已有棋子,請(qǐng)重新輸入!\n");
continue;
}
board[row][col] = 'x';
break;
}
}
void computerMove(char board[MAX_ROW][MAX_COL]) {
printf("輪到電腦落子");
while (1) {
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (board[row][col] != ' ') {
continue;
}
board[row][col] = 'o';
break;
}
}
int isFull(char board[MAX_ROW][MAX_COL]) {
for (int row = 0; row < MAX_ROW; row++) {
for (int col = 0; col < MAX_COL; col++) {
if (board[row][col] == ' ') {
//棋盤沒(méi)滿
return 0;
}
}
}
return 1;
}
int checkWinner(char board[MAX_ROW][MAX_COL]) {
//檢查所有行
for (int row = 0; row < MAX_ROW; row++) {
if (board[row][0] != ' ' && board[row][0] == board[row][1] && board[row][0] == board[row][2]) {
return board[row][0];
}
}
//檢查所有列
for (int col = 0; col < MAX_COL; col++) {
if (board[0][col] != ' ' && board[0][col] == board[1][col] && board[0][col] == board[2][col]) {
return board[0][col];
}
}
//檢查對(duì)角線
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ') {
return board[0][0];
}
if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] != ' ') {
return board[0][2];
}
if (isFull(board)) {
return 'q';
}
return ' ';
}
int main() {
char winner = ' ';
//1.創(chuàng)建一個(gè)棋盤,并初始化.
char board[MAX_ROW][MAX_COL] = { 0 };
//2.init函數(shù)將棋盤每個(gè)格子初始化成' '.
init(board);
while (1) {
//3.打印棋盤
printBoard(board);
//4.玩家落子
playerMove(board);
//5.判斷勝負(fù)
winner = checkWinner(board);
if (winner != ' ') {
//勝負(fù)已分
break;
}
//6.電腦落子
computerMove(board);
//7.判斷勝負(fù)
winner = checkWinner(board);
if (winner != ' ') {
//勝負(fù)已分
break;
}
}
if (winner == 'x') {
printf("恭喜你,你贏了!\n");
}else if(winner=='o') {
printf("你真菜連人工智障都玩不過(guò)\n");
}else {
printf("你和人工智障五五開\n");
}
return 0;
}
運(yùn)行界面如下:

到此這篇關(guān)于初學(xué)者練習(xí)--C語(yǔ)言寫三子棋小游戲的文章就介紹到這了,更多相關(guān)C語(yǔ)言寫三子棋小游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易三子棋游戲
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的三子棋游戲源碼
- C語(yǔ)言實(shí)現(xiàn)三子棋游戲含完整代碼
- C語(yǔ)言小游戲之簡(jiǎn)易版三子棋(棋盤可自由擴(kuò)展)
- C語(yǔ)言實(shí)現(xiàn)三子棋游戲(棋盤可變)
- 詳解用C語(yǔ)言實(shí)現(xiàn)三子棋游戲流程
- C語(yǔ)言實(shí)現(xiàn)的一個(gè)三子棋游戲詳解流程
- C語(yǔ)言三子棋游戲的簡(jiǎn)單設(shè)計(jì)
- C語(yǔ)言實(shí)現(xiàn)三子棋簡(jiǎn)單小游戲
- 一盤王者的時(shí)間用C語(yǔ)言實(shí)現(xiàn)三子棋
相關(guān)文章
Qt編寫地圖實(shí)現(xiàn)實(shí)時(shí)動(dòng)態(tài)軌跡效果
實(shí)時(shí)動(dòng)態(tài)軌跡主要是需要在地圖上動(dòng)態(tài)顯示GPS的運(yùn)動(dòng)軌跡,也是編寫地圖時(shí)一個(gè)重要的功能。本文將利用Qt實(shí)現(xiàn)這一功能,需要的可以參考一下2022-02-02
C++實(shí)現(xiàn)棧的操作(push和pop)
這篇文章主要介紹了C++實(shí)現(xiàn)棧的操作(push和pop),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
C語(yǔ)言實(shí)現(xiàn)繪制貝塞爾曲線的函數(shù)
貝塞爾曲線,又稱貝茲曲線或貝濟(jì)埃曲線,是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線。本文將利用C語(yǔ)言實(shí)現(xiàn)繪制貝塞爾曲線的函數(shù),需要的可以參考一下2022-12-12
C++ Boost Serialization庫(kù)超詳細(xì)獎(jiǎng)金額
Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱2022-12-12
C語(yǔ)言中的long型究竟占4個(gè)字節(jié)還是8個(gè)字節(jié)(遇到的坑)
小編在復(fù)習(xí)C語(yǔ)言的時(shí)候踩到了不少坑,糾結(jié)long類型究竟占4個(gè)字節(jié)還是8個(gè)字節(jié)呢?好,今天通過(guò)本文給大家分享下我的詳細(xì)思路,感興趣的朋友跟隨小編一起看看吧2021-11-11
C語(yǔ)言實(shí)現(xiàn)銀行管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)銀行管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
C語(yǔ)言基礎(chǔ)解析之分支與循環(huán)語(yǔ)句
C語(yǔ)言是一門結(jié)構(gòu)化的程序設(shè)計(jì)語(yǔ)言,當(dāng)C語(yǔ)言用來(lái)描述生活中的事物時(shí),會(huì)用到三種結(jié)構(gòu):順序結(jié)構(gòu)(不去贅述),選擇結(jié)構(gòu)(對(duì)應(yīng)分支語(yǔ)句),循環(huán)結(jié)構(gòu)(對(duì)應(yīng)循環(huán)語(yǔ)句),分支語(yǔ)句:分支語(yǔ)句分為兩種,一種是if語(yǔ)句,一種是switch語(yǔ)句2021-09-09
淺談C++高并發(fā)場(chǎng)景下讀多寫少的優(yōu)化方案
本文主要介紹了淺談C++高并發(fā)場(chǎng)景下讀多寫少的優(yōu)化方案,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01

