C語言小遊戲 - - 「三子棋」

2020-09-21 11:00:45

遊戲規則:
三子棋是一種民間傳統遊戲,又叫九宮棋、圈圈叉叉、一條龍、井字棋等。將正方形對角線連起來,相對兩邊依次擺上三個雙方棋子,只要將自己的三個棋子走成一條線,對方就算輸了。

程式碼採用模組化思想:

在這裡插入圖片描述
game.h 模組:
存放 標頭檔案和函數宣告

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//全域性變數,方便修改後期棋盤的大小
#define COL 3//列
#define ROW 3//行

#define COUNT 3

void menu(void);
void game(void);
void InitBoard(char board[ROW][COL], int row, int col);
void DisplayBoard(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col, int arr[]);
void ComMove(char board[ROW][COL], int row, int col, int arr[]);
char Winner(char board[ROW][COL], int row, int col, int arr[]);
int IsFull(char board[ROW][COL], int row, int col);

game.c 模組:
遊戲執行時 函數之間的呼叫
包括:選單列印、棋盤初始化、顯示棋盤、玩家和電腦落子位置的確定、判斷輸贏

#include "game.h"

//列印選單
void menu()
{
	printf("*************************\n");
	printf("**1.play*********0.exit**\n");
	printf("*************************\n");
}

//初始化棋盤
void InitBoard(char board[ROW][COL], int  row, int col)
{
	int i;
	int j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

//顯示棋盤
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i;
	int j;
	printf("     ");
	for (j = 0; j < col; j++)
	{
		printf("%2d  ", j + 1);
	}
	printf("\n\n");
	for (i = 0; i < row; i++)
	{
		printf("%3d  ", i + 1);
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n     ");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
		}
		printf("\n");
	}
}

//玩家落子
void PlayerMove(char board[ROW][COL], int row, int col, int arr[])
{
	int i;
	int j;

	printf("該玩家落子\n");
	printf("請輸入位置:");
	printf("例如:1 1(該位置對應棋盤左上角第一格,輸入完畢按enter鍵結束)\n");
	while (1)
	{
		scanf("%d %d", &i, &j);
		if ((i - 1) >= 0 && (i - 1) < row && (j - 1) >= 0 && (j - 1) < row)
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = 'X';
				arr[0] = i - 1;
				arr[1] = j - 1;
				return arr;
			}
			else
			{
				printf("該位置已有棋子,請重新輸入!!\n");
			}
		}
		else
		{
			printf("輸入座標不在棋盤範圍內,請重新輸入!!\n");
		}
	}
}
//電腦落子
void ComMove(char board[ROW][COL], int row, int col, int arr[])
{
	printf("該電腦落子:\n");
	int i;
	int j;
	while (1)
	{
		i = rand() % row;
		j = rand() % col;
		if (board[i][j] == ' ')
		{
			board[i][j] = 'O';
			arr[0] = i;
			arr[1] = j;
			return arr;
		}
	}
}

//判斷輸贏
char Winner(char board[ROW][COL], int row, int col, int arr[])
{
	int i;
	int j;
	int x = arr[0];
	int y = arr[1];
	int count[4] = { 1,1,1,1 };

	//向左檢查
	for (i = x + 1; i < row; i++)
	{
		if (board[i][y] == board[x][y] && board[x][y] != ' ')
		{
			(count[0])++;
		}
		else
		{
			break;
		}
	}
	//向右檢查
	for (i = x - 1; i >= 0; i--)
	{
		if (board[i][y] == board[x][y] && board[x][y] != ' ')
		{
			(count[0])++;
		}
		else
		{
			break;
		}
	}

	//向上檢查
	for (j = y + 1; j < col; j++)
	{
		if (board[x][j] == board[x][y] && board[x][y] != ' ')
		{
			(count[1])++;
		}
		else
		{
			break;
		}
	}

	//向下檢查
	for (j = y - 1; j >= 0; j--)
	{
		if (board[x][j] == board[x][y] && board[x][y] != ' ')
		{
			(count[1])++;
		}
		else
		{
			break;
		}
	}

	//向右上檢查
	i = x + 1;
	j = y + 1;
	while (i < row && j < col)
	{
		if (board[i][j] == board[x][y] && board[x][y] != ' ')
		{
			(count[2])++;
			i++;
			j++;
		}
		else
		{
			break;
		}
	}
	//向左下檢查
	i = x - 1;
	j = y - 1;
	while (i >= 0 && j >= 0)
	{
		if (board[i][j] == board[x][y] && board[x][y] != ' ')
		{
			(count[2])++;
			i--;
			j--;
		}
		else
		{
			break;
		}
	}

	//向左上檢查
	i = x - 1;
	j = y + 1;
	while (i >= 0 && j < col)
	{
		if (board[i][j] == board[x][y] && board[x][y] != ' ')
		{
			(count[3])++;
			i--;
			j++;
		}
		else
		{
			break;
		}
	}

	//向右下檢查
	i = x + 1;
	j = y - 1;
	while (i < row && j >= 0)
	{
		if (board[i][j] == board[x][y] && board[x][y] != ' ')
		{
			(count[3])++;
			i++;
			j--;
		}
		else
		{
			break;
		}
	}

	for (i = 0; i < 4; i++)
	{
		if (count[i] >= COUNT)
		{
			return board[x][y];
		}
	}

	//棋盤是否滿?
	int ret = IsFull(board, ROW, COL);
	if (ret)
	{
		return 'E';
	}
	return 'C';
}

//判斷棋盤是否落滿子
int IsFull(char board[ROW][COL], int row, int col)
{
	int i;
	int j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < row; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}



//遊戲主體
void game()
{
	char ret;

	//用於接收落子座標
	int arr[2];

	//遊戲介面部分
	//建立一個棋盤
	char board[ROW][COL] = { 0 };
	//初始化棋盤
	InitBoard(board, ROW, COL);
	//列印棋盤
	DisplayBoard(board, ROW, COL);

	//遊戲功能部分
	while (1)
	{
		//玩家落子
		PlayerMove(board, ROW, COL, arr);
		DisplayBoard(board, ROW, COL);
		ret = Winner(board, ROW, COL, arr);
		if (ret != 'C')
		{
			break;
		}
		//電腦落子
		ComMove(board, ROW, COL, arr);
		printf("電腦落子位置是:(%d,%d)\n", arr[0] + 1, arr[1] + 1);
		DisplayBoard(board, ROW, COL, arr);
		ret = Winner(board, ROW, COL, arr);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == 'X')
	{
		printf("恭喜你,勝利!\n\n\n");
	}
	else if (ret == 'O')
	{
		printf("很遺憾,失敗了!\n\n\n");
	}
	else
	{
		printf("旗鼓相當,打成平局\n\n\n");
	}
}

test.c 模組:
程式的入口,寫main函數,用來呼叫本次遊戲執行所需的函數


#include "game.h"

int main()
{
	int input = 0 ;
	srand((unsigned int)time(NULL));//給出亂數值
	printf("****三子棋遊戲****\n");
	printf("玩家執子:*;電腦執子:#\n");
	do
	{
		menu();
		printf("請選擇:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("遊戲結束。\n");
			break;
		default:
			printf("輸入錯誤,請重新輸入!!!\n\n");
			break;
		}
	} while (input);
	return 0;
}