利用C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)小游戲
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)小游戲的具體代碼,供大家參考,具體內(nèi)容如下
推薦閱讀順序(不建議跳過)
先看實(shí)現(xiàn)之后的界面 —— 然后看分析程序要實(shí)現(xiàn)的步驟 —— 之后在看翻到test.c部分 —— 在test.c中找到main()函數(shù) —— 從main函數(shù)的第一步開始看 —— 遇到自定義函數(shù)請(qǐng)到game.h源文件中找到相應(yīng)函數(shù)的詳情
輔助閱讀:
game.h文件中放的是函數(shù)的聲明(引用頭文件)
game.c文件中放的是函數(shù)的詳情(怎么用代碼實(shí)現(xiàn)相應(yīng)步驟的)
test.c文件中放的是整體的大致思路
用不同文件分裝代碼是為了:能夠讓自己的代碼更有條理,思路更加的清晰,別人也更容易看懂
如果覺得翻來翻去太過于麻煩:請(qǐng)登錄自己現(xiàn)在所用的編譯器 —— 把代碼先拷貝一份(按照不同的文件分裝) —— 遇到自定義函數(shù)(把鼠標(biāo)放在函數(shù)名上面、右擊、轉(zhuǎn)到定義)(這樣編譯器可以直接轉(zhuǎn)到game.c文件中的函數(shù)詳情)
實(shí)現(xiàn)之后的的界面
分析程序要實(shí)現(xiàn)的步驟
1、在屏幕上打印菜單(提示你要選擇的內(nèi)容)
2、定義數(shù)組,初始化數(shù)組(把數(shù)組中的元素全替換成空格)
3、把數(shù)組打印出來
4、玩家下棋
5、判斷輸贏(四種情況:玩家贏、玩家輸、平局、游戲未結(jié)束,繼續(xù))
6、電腦下棋
7、判斷輸贏(四種情況:玩家贏、玩家輸、平局、游戲未結(jié)束,繼續(xù))
8、可以多次玩這個(gè)游戲
test.c(源文件)
用于放整體的大致思路,自定義函數(shù)放在game.h文件中
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void menu() { printf("+-------------------------------------+\n"); printf("| 1.玩游戲 |\n"); printf("| 0.退出游戲 |\n"); printf("+-------------------------------------+\n"); } void game() { //定義棋盤數(shù)組 //其中 Hang和Lie 是define定義的標(biāo)識(shí)符常量 —— 在game.h文件中可以找到 //Hang表示有幾行 —— Lie表示有幾列 char board[Hang][Lie]; char ret = ' '; //初始化棋盤數(shù)組 //傳入三個(gè)變量,數(shù)組首元素地址,行,列 //在game.h中聲明這個(gè)函數(shù),在game.c中實(shí)現(xiàn)這個(gè)函數(shù),完成以上兩步在這里直接使用就可以了 init_board(board, Hang, Lie); //進(jìn)入這個(gè)函數(shù)——跳轉(zhuǎn)到game.c文件,代碼上方注釋有1的部分 //打印棋盤的界面 —— 把棋盤顯示出來 —— 進(jìn)入這個(gè)函數(shù)——跳轉(zhuǎn)到game.c文件,代碼上方注釋有2的部分 checker_board(board, Hang, Lie); while (1) { //玩家走—— 進(jìn)入這個(gè)函數(shù)——跳轉(zhuǎn)到game.c文件,代碼上方注釋有3的部分 player_move(board, Hang, Lie); checker_board(board, Hang, Lie); //判斷輸贏 —— 進(jìn)入這個(gè)函數(shù)——跳轉(zhuǎn)到game.c文件,代碼上方注釋有5的部分 ret = win_or_lose(board, Hang, Lie); if (ret != 'C') { break; } //電腦走 —— 進(jìn)入這個(gè)函數(shù)——跳轉(zhuǎn)到game.c文件,代碼上方注釋有4的部分 computer_move(board, Hang, Lie); checker_board(board, Hang, Lie); //判斷輸贏 ret = win_or_lose(board, Hang, Lie); if (ret != 'C') { break; } } if (ret == 'Q') { printf("平局\n"); } if (ret == '*') { printf("恭喜你:贏\n"); } if (ret == '#') { printf("很遺憾:你輸了\n"); } } int main() { int input = 0; srand((unsigned int)time(NULL)); //生成隨機(jī)數(shù)要用到rand() //用rand()要調(diào)用srand() //srand()其中()中要用到不斷變化的量 —— 用時(shí)間戳來做不斷變化的量 —— 時(shí)間戳可以用time()函數(shù)來實(shí)現(xiàn) //(unsigned int) —— 是強(qiáng)制類型轉(zhuǎn)換 //srand()函數(shù)不用引用多次,所以放在循環(huán)的前面就可以了 //這個(gè)生成隨機(jī)數(shù)我在前面一篇博文中也講了,如果不明白也可以去上篇博文看一下 do { menu(); //打印簡(jiǎn)單的菜單界面(這個(gè)函數(shù)不用去game.c文件中去找,就在這個(gè)文件的上方) printf("請(qǐng)輸入選項(xiàng)前面的序號(hào)>:"); scanf("%d", &input); switch (input) //switch選擇語(yǔ)句是實(shí)現(xiàn):輸入1玩游戲,輸入0退出游戲,輸入其他數(shù)提示輸入錯(cuò)誤。 { case 1: //game()自定義函數(shù) --- 在這個(gè)函數(shù)里面實(shí)現(xiàn)三子棋游戲 —— 主要的設(shè)計(jì)思路都在這個(gè)函數(shù)中 //這個(gè)函數(shù)也在這個(gè)文件的上方,不用去game.c文件中找 game(); //進(jìn)入函數(shù) break; case 0: printf("退出游戲\n"); break; default: printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n"); break; } } while (input); return 0; }
game.h(頭文件)
放函數(shù)的聲明(引用頭文件)
#pragma once #include<stdio.h> #include<time.h> #include<stdlib.h> #define Hang 3 #define Lie 3 //初始化棋盤,把棋盤中的數(shù)變成空格; void init_board(char board[Hang][Lie], int hang, int lie); //打印期棋盤,顯示棋盤狀態(tài); void checker_board(char board[Hang][Lie], int hang, int lie); //玩家走 void player_move(char board[Hang][Lie], int hang, int lie); //電腦走 void computer_move(char board[Hang][Lie], int hang, int lie); //判斷輸贏 char win_or_lose(char board[Hang][Lie], int hang, int lie);
game.c (源文件)
放函數(shù)詳情(怎么用代碼實(shí)現(xiàn)相應(yīng)步驟的)
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" //1111111111 //把數(shù)組中的數(shù)初始化成空格 void init_board(char board[Hang][Lie], int hang, int lie) { int i = 0; for (i = 0; i < hang; i++) { int j = 0; for (j = 0; j < lie; j++) { board[i][j] = ' '; } } } //2222222222 //打印棋盤 void checker_board(char board[Hang][Lie], int hang, int lie) { int i = 0; for (i = 0; i < hang; i++) { int j = 0; for (j = 0; j < lie; j++) //打印第一行棋盤 { printf(" %c ", board[i][j]); if (j < lie - 1) { printf("|"); } } printf("\n"); if (i < hang - 1) { for (j = 0; j < lie; j++) { printf("---"); if (j < lie - 1) { printf("|"); } } } printf("\n"); } } //3333333333 //玩家輸入 —— 判斷玩家輸入的坐標(biāo) //如果超過數(shù)組范圍,顯示輸入錯(cuò)誤,請(qǐng)重新輸入 //如果下棋的位置已經(jīng)被占用,顯示坐標(biāo)錯(cuò)誤 void player_move(char board[Hang][Lie], int hang, int lie) { int x = 0; int y = 0; printf("請(qǐng)輸入你所要下的位置坐標(biāo):"); while (1) //這個(gè)循環(huán)結(jié)束的條件是:玩家輸入正確的 { scanf("%d %d", &x, &y); //玩家輸入坐標(biāo) if (x > 0 && x <= hang && y > 0 && y <= lie) { if (board[x - 1][y - 1] == ' ') //輸入數(shù)正確 { board[x - 1][y - 1] = '*'; break; } else //輸入數(shù)對(duì)應(yīng)的坐標(biāo)已被占用 { printf("坐標(biāo)錯(cuò)誤:"); } } else //輸入數(shù)超出數(shù)組范 { printf("輸入錯(cuò)誤請(qǐng)重新輸入:"); } } } //4444444444 //電腦走 void computer_move(char board[Hang][Lie], int hang, int lie) { int hangs = 0; int lies = 0; printf("電腦走:\n"); while(1) //這個(gè)循環(huán)結(jié)束的條件是:直到執(zhí)行隨機(jī)坐標(biāo)正確(沒有被占用) { //生產(chǎn)隨機(jī)坐標(biāo) int hangs = rand() % hang; int lies = rand() % lie; if (board[hangs][lies] == ' ') //判斷坐標(biāo)是否被占用 { board[hangs][lies] = '#'; break; } } } //5555555555 //判斷4種狀態(tài); //1、玩家贏,返回* //2、電腦贏, 返回# //3、平局 返回Q //4、繼續(xù) 返回C char win_or_lose(char board[Hang][Lie], int hang, int lie) { int i = 0; int j = 0; int count = 0; //以下判斷是電腦贏還是玩家贏 //贏(8中情況)得條件:一行三個(gè)都相同 或者 一列三個(gè)都相同 或者 對(duì)角線相同 for (i = 0; i < hang; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ') { return board[i][0]; } if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') { return board[0][i]; } } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') { return board[1][1]; } //以下是判斷是不是平局 //平局條件:數(shù)組中沒有空格(都被占滿了) 并且 已經(jīng)判斷出來玩家電腦都沒贏 for (i = 0; i < hang; i++) { for (j = 0; j < lie; j++) { if (board[i][j] == ' ') { count++; } } } if (count == 0) { return 'Q'; } //不是平局,不是電腦贏,不是玩家贏,剩下的就是繼續(xù)玩 return 'C'; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Qt5實(shí)現(xiàn)qDebug日志信息寫入日志文件過程
這篇文章主要為大家介紹了Qt5實(shí)現(xiàn)qDebug日志信息寫入日志文件的過程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05C++實(shí)現(xiàn)LeetCode(58.求末尾單詞的長(zhǎng)度)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(58.求末尾單詞的長(zhǎng)度),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++利用棧實(shí)現(xiàn)中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式
這篇文章主要為大家詳細(xì)介紹了C++利用棧實(shí)現(xiàn)中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04詳解C++編程中的sizeof運(yùn)算符與typeid運(yùn)算符
這篇文章主要介紹了C++編程中的sizeof運(yùn)算符與typeid運(yùn)算符,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01淺析C語(yǔ)言調(diào)試器GDB和LLDB的使用方法
這篇文章主要介紹了C語(yǔ)言調(diào)試器GDB和LLDB的使用方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12