五子棋代码

#ifndef _GO_BANG_
#define _GO_BANG_

#include <iostream>

#include <cstdio>
#include <cstdlib>
#include <cstring>

#define ROW 15
#define COL 15
#define BLACK 'B'
#define WHITE 'O'

/**
 * 棋盘初始化函数,提供当前函数的参数是个 char 类型二维数组,
 * 数组的一维下标和二维下标由 ROW 和 COL 两个宏常量控制
 *
 * @param chess_board 用户提供的 char 类型二维数组
 */
void gobang_ui_init(char chess_board[][COL]);

/**
 * 棋盘展示函数,,提供当前函数的参数是个 char 类型二维数组,
 * 数组的一维下标和二维下标由 ROW 和 COL 两个宏常量控制
 *
 * @param chess_board 用户提供的 char 类型二维数组
 */
void show_chess_board(char chess_board[][COL]);

/**
 * 落子函数,根据当前玩家提供的行列下标位置,落子对应玩家的棋子
 * 
 * @param chess_board 当前五子棋对应的棋盘 char 类型二维数组
 * @param row_index   用户指定落子的行下标位置
 * @param col_index   用户指定落子的列下标位置
 * @param player      对应用户,利用 BLACK 和 WHITE 两个宏区分用户玩家
 * @return 落子成功返回 1,否则返回 0
 */
int place_stone(char chess_board[][COL], int row_index, int col_index, char player);


/**
 * 判断是否游戏获胜条件
 * 
 * @param chess_board 当前五子棋对应的棋盘 char 类型二维数组
 * @param row_index   用户指定落子的行下标位置
 * @param col_index   用户指定落子的列下标位置
 * @param player      对应用户,利用 BLACK 和 WHITE 两个宏区分用户玩家
 * @return 游戏胜利返回 1,否则返回 0
 */
int is_win(char chess_board[][COL], int row_index, int col_index, char player);

#endif
#include "gobang.h"

using namespace std;

void gobang_ui_init(char chess_board[][COL])
{
    memset(chess_board, '+', ROW * COL);
}

void show_chess_board(char chess_board[][COL])
{
    cout << "  1 2 3 4 5 6 7 8 9 A B C D E F" << endl;

    for (int i = 0; i < ROW; i++)
    {
        if (i + 1 < 10)
        {
            cout << i + 1;
        }
        else
        {
            cout << (char)('A' + i - 9);
        }
        for (int j = 0; j < COL; j++)
        {
            cout << ' ' << chess_board[i][j];
        }

        cout << endl;
    }
}

int place_stone(char chess_board[][COL], int row_index, int col_index, char player)
{
    row_index -= 1;
    col_index -= 1;
    if (row_index < 0 || row_index > ROW - 1 || col_index < 0 || col_index > COL - 1 || chess_board[row_index][col_index] != '+')
    {
        cout << "您落子的下标位置不符合游戏规则" << endl;
        return 0;
    }

    chess_board[row_index][col_index] = player;

    return 1;
}

int is_win(char chess_board[][COL], int row_index, int col_index, char player)
{
    row_index -= 1;
    col_index -= 1;

    /*
    横向判断
        row_index 不变
        col_index 在不超过合理下标范围以内的情况下,-4 作为左侧限制,+4 作为右侧限制
    */
    /*
    count 记录当前玩家对应棋子的连续总个数。
    */
    int count = 0;

    for (int j = (col_index - 4 > 0 ? col_index - 4 : 0);
         j <= (col_index + 4 > COL - 1 ? COL - 1 : col_index + 4);
         j++)
    {
        if (chess_board[row_index][j] == player)
        {
            count += 1;

            if (5 == count)
            {
                return 1;
            }
        }
        else
        {
            count = 0;
        }
    }

    count = 0;

    /*
    纵向判断
        col_index 不变
        row_index 在不超过合理下标范围以内的情况下,-4 作为顶部限制,+4 作为底部限制
    */
    for (int i = (row_index - 4 > 0 ? row_index - 4 : 0);
         i <= (row_index + 4 > ROW - 1 ? ROW - 1 : row_index + 4);
         i++)
    {
        if (chess_board[i][col_index] == player)
        {
            count += 1;

            if (5 == count)
            {
                return 1;
            }
        }
        else
        {
            count = 0;
        }
    }

    /*
    \ 正对角方向
    需要明确
        1. 左上角起始下标位置
        2. 右下角终止下标位置
        3. row_index 和 col_index 下标都是递增关系。
    */

    // 左上角起始下标位置
    int left_row_dist = row_index - 4 > 0 ? 4 : row_index - 0;
    int left_col_dist = col_index - 4 > 0 ? 4 : col_index - 0;

    int left_min_dist = left_row_dist > left_col_dist ? left_col_dist : left_row_dist;
    /*
    左侧起始下标位置是
        [row_index - left_min_dist][col_index - left_min_dist]
    */

    // 右下角终止下标位置
    int right_row_dist = row_index + 4 > ROW - 1 ? ROW - 1 - row_index : 4;
    int right_col_dist = col_index + 4 > COL - 1 ? COL - 1 - col_index : 4;

    int right_min_dist = right_row_dist > right_col_dist ? right_col_dist : right_row_dist;

    /*
    右侧终止下标位置是
        [row_index + right_min_dist][col_index + right_min_dist]
    */
    count = 0;

    for (int i = row_index - left_min_dist, j = col_index - left_min_dist;
         i <= row_index + right_min_dist && j <= col_index + right_min_dist;
         i++, j++)
    {
        if (chess_board[i][j] == player)
        {
            count += 1;

            if (5 == count)
            {
                return 1;
            }
        }
        else
        {
            count = 0;
        }
    }

    /*
    / 反对角方向
    需要明确
        1. 左下角起始下标位置
            row_index + 4 判断
            col_index - 4 判断
        2. 右上角终止下标位置
            row_index - 4 判断
            col_index + 4 判断
        3. row_index 行下标递减关系,col_index 列下标递增关系
    */
    left_row_dist = row_index + 4 > ROW - 1 ? ROW - 1 - row_index : 4;
    left_col_dist = col_index - 4 > 0 ? 4 : col_index - 0;

    left_min_dist = left_row_dist > left_col_dist ? left_col_dist : left_row_dist;
    /*
    左下角起始下标位置
        [row_index + left_nmin_dist][col_index - left_min_dist];
    */

    right_row_dist = row_index - 4 > 0 ? 4 : row_index - 0;
    right_col_dist = col_index + 4 > COL - 1 ? COL - 1 - row_index : 4;

    right_min_dist = right_row_dist > right_col_dist ? right_col_dist : right_row_dist;
    /*
    右上角终止下标位置
        [row_index - right_min_dist][col_index + right_min_dist];
    */
    for (int i = row_index + left_min_dist, j = col_index - left_min_dist;
         i >= row_index - right_min_dist, j <= col_index + right_min_dist;
         i--, j++)
    {
        if (chess_board[i][j] == player)
        {
            count += 1;

            if (5 == count)
            {
                return 1;
            }
        }
        else
        {
            count = 0;
        }
    }

    return 0;
}
#include <iostream>

#include "gobang.h"

using namespace std;

int main(int argc, char const *argv[])
{   
    int ret = 0;
    /**
     * flag 是一个游戏胜利判断条件
     */
    int flag = 0;
    /**
     * 记录当前落子的总个数,同时可以利用 % 2 判断
     * 落子的玩家是哪一个玩家
     */
    int count = 0;
    int row_index = 0;
    int col_index = 0;
    char player = '\0';
    char chess_board[ROW][COL] = {'\0'};

    gobang_ui_init(chess_board);

    while (1)
    {
        show_chess_board(chess_board);

        if (count % 2 == 0)
        {
            cout << "执黑落子";
            player = BLACK;
        }
        else
        {
            cout << "执白落子";
            player = WHITE;
        }

        cout << ",请输入对应的下标位置, 例如 : 2 3 : ";
        cin >> row_index >> col_index;

        ret = place_stone(chess_board, row_index, col_index, player);

        if (ret)
        {
            flag = is_win(chess_board, row_index, col_index, player);
            cout << "flag = " << flag << endl;
        }

        count += ret;

        if (flag)
        {
            cout << (player == BLACK ? "执黑获胜" : "执白获胜") << endl;
            break;
        }

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值