200行C語言代碼實現簡易三子棋遊戲

前言

三子棋應該是是我們最早接觸到的棋類遊戲,用C語言實現三子棋對初學者來說是一種不錯的鍛煉

編寫三子棋隻需要用到數組、函數和生成隨機數的知識,所以比較適合成為編程學習者編寫的第一個小遊戲。

一.代碼實現

第一部分是源碼復制就可以使用,每一個自定義函數在第二部分設計思路中都有詳細解釋,結合代碼實現設計思路理解會有一個更好的效果

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<time.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
void reset(char arr[ROW][COL])//將棋盤arr[ROW][COL]數據賦值為空格
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			arr[i][j] = ' ';
		}
	}
}
void dis_play(char arr[ROW][COL])//打印棋盤
{
	for (int i = 0; i < ROW; i++)//for每一次進去,打印一行數組和一條分割線
	{	                         //數組行為:(空格)元素(空格)|(空格)元素(空格)|(空格)元素(空格)
		                         //分割線為: -      -      -   |   -      -     -   |   -     -      -
  		for (int j = 0; j < COL; j++)//一行數組
		{
			printf(" %c ", arr[i][j]);
			if (j < COL - 1)//為瞭美觀,最後的“|”不打印
			{
				printf("|");
			}
		}
		printf("\n");
		for (int k = 0; k < COL; k++)//一行分割線
		{
			printf("---");
			if (k < COL - 1)//為瞭美觀,最後的“|”不打印
			{
				printf("|");
			}
		}
		printf("\n");
	}
}
void player_move(char arr[ROW][COL])//玩傢下棋
{
	int row = 0, col = 0;
	while (1)
	{
		printf("玩傢下棋,請輸入坐標>:");
		scanf("%d %d", &row, &col);
		if (arr[row - 1][col - 1] == ' ')//判斷是否可以下棋
		{
			arr[row - 1][col - 1] = '*';
			break;
		}
		printf("輸入錯誤,請再次輸入\n");
	}
}
void computer_move(char arr[ROW][COL])//電腦下棋
{
	int row = rand() % ROW;//生成行號
	int col = rand() % COL;//生成列標
	printf("電腦下棋:>\n");
	while (1)
	{
		if (arr[row][col] == ' ')//判斷是否可以下棋
		{
			arr[row][col] = '#';
			break;
		}
		row = rand() % ROW;
		col = rand() % COL;
	}
}
int is_full(char arr[ROW][COL])//用於在is_win()中判斷是否為平局
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (arr[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}
char is_win(char arr[ROW][COL])//三子棋勝利無非就三種情況:行相同、列相同和對角線相同。除開勝利還有平局
{
	for (int i = 0; i < ROW; i++)//判斷行
	{
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ')
			return arr[i][0];
	}
	for (int i = 0; i < COL; i++)//判斷列
	{
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
			return arr[0][i];
	}
	//判斷對角線
	if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
		return arr[0][0];
	if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')
		return arr[0][2];
	//判斷平局
	if (is_full(arr))
	{
		return 'q';
	}
	//都不滿足遊戲繼續運行 return ‘c'
	return 'c';
}
void meau()
{
	printf("------------------\n");
	printf("|     1.play     |\n");
	printf("|----------------|\n");
	printf("|     0.exit     |\n");
	printf("------------------\n");
}
void game()
{
	char arr[ROW][COL];//初始化棋盤
	char ch;
	reset(arr);//將棋盤裡每一個元素賦值為空格
	dis_play(arr);
	do
	{
		player_move(arr);
		dis_play(arr);
		ch=is_win(arr);
		if (ch != 'c')
		{
			break;
		}
		computer_move(arr);
		dis_play(arr);
		ch=is_win(arr);
		if (ch != 'c')
		{
			break;
		}
	} while (1);
	switch (ch)//根據返回字符判斷結果
	{
	case '#':
		printf("電腦勝利\n"); break;
	case '*':
		printf("玩傢勝利\n"); break;
	case 'q':
		printf("平局\n"); break;
	}
}
int main()
{
	srand((unsigned)time(NULL));
	int input = 0;
	do 
	{
		meau();
		scanf("%d", &input);
		switch (input)
		{
		case 1 :
			game(); break;
		case 0 :
			break;
		default :
			printf("輸入錯誤\n");
		}
	} while (input);
	return 0;
}

二.設計思路

main()函數搭建框架

1.main()函數搭建框架:像所有的電腦遊戲一樣,我們需要一個菜單,通過菜單選擇進入遊戲和退出遊戲,當一盤遊戲結束時可以再次選擇進入或者退出,菜單用printf()打印就可以解決,循環的進入遊戲用do while()循環就可以解決

實現代碼如下

 void meau()
    {
	  printf("------------------\n");
	  printf("|     1.play     |\n");
	  printf("|----------------|\n");
	  printf("|     0.exit     |\n");
	  printf("------------------\n");
    } 
    void game()
{
	·········
}
int main()
{
    

	int input = 0;
	do 
	{
		meau();
		scanf("%d", &input);
		switch (input)
		{
		case 1 :
			game(); break;
		case 0 :
			break;
		default :
			printf("輸入錯誤\n");
		}
	} while (input);
	
	return 0;
}

2.當我們進入case 1,運行game()函數;首先我們需要一個容器來存放我們的遊戲數據,此時創建字符二維數組arr[3][3]作為容器,玩傢下的棋用“*”表示電腦用”#“表示。因為行和列都為3,後面經常要使用,我們對他進行宏定義一下

#define ROW 3
#define COL 3

dis_play( )函數

》.dis_play( ):我們下棋肯定需要棋盤來顯示我們的數據,我們通過構造一個函數dis_play()將數組打印出來來實現這一功能

dis_play()的功能其實就是把arr[ROW][COL]以棋盤形式打印顯示出來,需要借助一些特殊字符”|“和”_“輔助打印

#define ROW 3 / 行:3
#define COL 3 / 列:3
void dis_play(char arr[ROW][COL])
{
	for (int i=0;i<ROW;i++) /for每一次進去,打印一行數組和一條分割線
	{
		for (int j = 0; j < COL; j++)//打印數組
		{
			printf(" %c ", arr[i][j]);
			if (j < COL - 1)
			{
				printf("|");
			}
			
		}
		printf("\n");
		for (int k = 0; k < COL; k++)//打印分割線
		{
			printf("---");
			if (k < COL - 1)
			{
				printf("|");
			}
			
		}
		printf("\n");
	}
}

初步運行代碼,打印棋盤:

reset ( )函數

reset ( ) :我們下完一盤棋,還想下該怎麼辦?這時候我們構造一個函數reset(),將棋盤數組的每一個元素重置為空格

reset()函數,遍歷數組,賦值為空格

void reset( char arr[ROW][COL])
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			arr[i][j] = ' ';//賦值空格
		}
	}
}

player_move( )函數

player_move( ):玩傢下棋,不能隨便下,下過的地方不能下,我們構造一個player_move()函數完成這一功能

player_move( )函數功能其實就是為數組arr[ROW][COL]賦值,數組元素為空格的地方就是可以下棋的地方
輸入坐標時,和我們程序員思維不同,正常人認為行是從1開始而不是從0開始,玩傢輸入的數據需要減1才能正常賦值

void player_move(char arr[ROW][COL])
{
	int row = 0, col = 0;
	while (1)
	{
		printf("玩傢下棋,請輸入坐標>:");
		scanf("%d %d", &row, &col);
		if (arr[row-1][col-1] == ' ')
		{
			arr[row-1][col-1] = '*';
			break;
		}
		printf("輸入錯誤,請再次輸入\n");
	}
}

玩傢下棋

computer_move()函數

computre_move()電腦下棋,為瞭更容易實現我們這裡讓他再棋盤上隨機下,需要生成隨機數的知識,我們需要構造一個函數

使用頭文件#include<stdlib.h>中的rand()函數可以生成一個0~32767的偽隨機數,但使用rand()前先要使用srand()設置偽隨機數起點
起點隻要寫一次,我們將srand((unsigned)time(NULL))定義在主函數,此處是一種固定的寫法,time()函數需要引<time.h>頭文件

將rand()%3即%ROW可以生產0、1、2這三個隨機數,可以用來做數組的行號和列標

int main()
{
	srand((unsigned)time(NULL));/設置起點的固定寫法
	int input = 0;
	do 
	{
		meau();
		scanf("%d", &input);
		switch (input)
		{
		case 1 :
			game(); break;
		case 0 :
			break;
		default :
			printf("輸入錯誤\n");
		}
	} while (input);
	return 0;
}
void computer_move(char arr[ROW][COL])
{
	int row = rand() % ROW ;//利用隨機數生成行號列標
	int col = rand() % COL ;
	printf("電腦下棋:>\n");
	while (1)
	{
		if (arr[row][col] == ' ')//判斷是否為空格
		{
			arr[row][col] = '#';
			break;
		}
		row = rand() % ROW;
		col = rand() % COL;
	}
}

電腦下棋

is_win()函數

is_win()光下棋也不行,每當玩傢或電腦下一步棋必須有東西來判斷到底是玩傢贏瞭還是電腦贏瞭還是平局還是繼續,我們構造is_win()函數完成這一功能

is_win()函數功能最後是返回一個字符,電腦贏返回"#",玩傢贏返回”*“,平局返回”q“,以上情況都不符合就返回”c“(continue)
三子棋勝利無非就三種情況:行相同、列相同和對角線相同我們用for和if語句就可以判斷
平局的情況其實就是棋盤滿瞭,我們構造一個is_fuii()函數,棋盤滿瞭,該函數返回1否則返回0;

int is_full(char arr[ROW][COL])
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (arr[i][j] == ' ')/棋盤還有空格則return 0
				return 0;
		}
	}
	return 1;
}
char is_win(char arr[ROW][COL])  /is_win()函數
{
	for (int i = 0; i < ROW; i++)/判斷是否有行相同
	{
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][0] != ' ')
			return arr[i][0];
	}
	for (int i = 0; i <COL; i++)/判斷是否有列相同
	{
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
			return arr[0][i];
	}
	  /判斷對角線是否相同
	if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
		return arr[0][0];
	if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')
		return arr[0][2];
	if (1==is_full(arr))/is_full()返回1則return ‘q'
	{
		return 'q';
	}
		return 'c';/都不滿足,return ‘c'
}

總結

到此這篇關於200行C語言代碼實現簡易三子棋遊戲的文章就介紹到這瞭,更多相關C語言三子棋遊戲內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: