控制台版五子棋实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 五子棋
{
class Program
{
///
/// 游戏规则
///
public static string[] Gz = new string[]
{
" 游戏规则:",
" 1.双方分别使用黑白两色的棋子,空棋盘开局。",
" 2.黑色棋子先下,白色棋子后下,每次只能下一子。",
" 3.先形成5子连线者获胜",
" 操作简介:",
" 1.黑子通过wasd键移动选择落子点,空格键落子",
" 2.白子通过↑↓←→键移动选择落子点,空格键落子"
};

    /// <summary>
    /// 操作记录
    /// </summary>
    public static List<CzjlModel> Czjl = new List<CzjlModel>();

    /// <summary>
    /// 棋子集合.
    /// </summary>
    public static List<QzModel> QzList = new List<QzModel>();

    /// <summary>
    /// 棋盘大小
    /// </summary>
    public static int size = 16;

    /// <summary>
    /// 当前回合数
    /// </summary>
    public static int huihe = 1;

    /// <summary>
    /// 当前落子方,0白棋1黑棋
    /// </summary>
    public static int type = 0;

    /// <summary>
    /// 光标输入位置x
    /// </summary>
    public static int index_X = 0;

    /// <summary>
    /// 光标输入位置y
    /// </summary>
    public static int index_Y = 0;

    /// <summary>
    /// 程序入口
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
        //定义结束状态bool变量
        bool is_end = true;
        // 初始化光标位置到棋盘中央
        index_X = size;// 棋盘由字符■组成,由于■占两个字符位置,所以用/2处理
        index_Y = size / 2;

        // 循环检测游戏是否结束
        while (is_end)
        {
            // 清空控制台内容,达到刷新效果
            Console.Clear();
            // 绘制棋盘
            Draw_Qp(size);

            //打印落子记录
            if (type == 0)
            {
                Draw_Czjl("白子");
            }
            else
            {
                Draw_Czjl("黑子");
            }

            // 设置光标输入点位置
            Console.SetCursorPosition(index_X, index_Y);
            // 定义落子状态
            bool is_lz = true;
            // 检测落子状态
            while (is_lz)
            {
                // 接收键盘按键信息
                if (DownKey(Console.ReadKey(true).Key))
                {
                    is_lz = false;
                }
                else
                {
                    is_lz = true;
                }
            }
            //获取白棋集合
            List<QzModel> bqList = QzList.Where(r => r.Type == 0).ToList();
            //获取黑棋集合
            List<QzModel> hqList = QzList.Where(r => r.Type == 1).ToList();
            //落子后进行胜负检测
            if (IsWin(bqList))
            {
                Console.WriteLine("白棋胜");
                is_end = false;
            }
            if (IsWin(hqList))
            {
                Console.WriteLine("黑棋胜");
                is_end = false;
            }

        }

        Console.Read();
    }

    /// <summary>
    /// 绘制棋盘
    /// </summary>
    /// <param name="size">棋盘大小</param>
    public static void Draw_Qp(int size)
    {
        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                //当棋盘上有棋子时绘制棋子
                if (QzList.Where(r => r.Y == i && r.X / 2 == j).ToList().Count > 0)
                {
                    if (QzList.Where(r => r.Y == i && r.X / 2 == j).ToList().Last().Type == 1)
                    {
                        Console.Write("○");
                    }
                    else
                    {
                        Console.Write("●");
                    }
                    continue;
                }
                //没有棋子时绘制棋盘
                Console.Write("■");
            }
            //打印游戏规则
            if (Gz.Length > i)
            {
                Console.Write(Gz[i]);
            }
            //换行
            Console.WriteLine();
        }
    }

    /// <summary>
    /// 打印落子记录
    /// </summary>
    /// <param name="content">操作内容</param>
    /// <param name="type">操作人</param>
    public static void Draw_Czjl(string type)
    {
        // 按序号对落子记录排序,只打印最新的三条
        var Czjl_sort = Czjl.OrderByDescending(r => r.Sort).ToList().Take(3).ToList();
        // 打印系统消息
        if (type == "白子")
        {
            if (Czjl_sort.Count > 0)
            {
                Console.WriteLine("第" + huihe + "回合,请白棋落子!");
            }
            else
            {
                Console.WriteLine("第1回合,请白棋落子!");
            }
        }
        else
        {
            if (Czjl_sort.Count > 0)
            {
                Console.WriteLine("第" + huihe + "回合,请黑棋落子!");
            }
            else
            {
                Console.WriteLine("第1回合,请黑棋落子!");
            }
        }
        Console.WriteLine();
        Console.WriteLine();
        //打印落子记录
        foreach (var i in Czjl_sort)
        {
            Console.WriteLine(i.Content);
        }
    }

    /// <summary>
    /// 胜负校验
    /// </summary>
    /// <param name="QzList">棋子集合</param>
    public static bool IsWin(List<QzModel> QzList)
    {
        bool is_win = false;// 胜负状态
        int lx_number = 1;//连珠数量
        //当棋子数不够时不进行检测
        if (QzList.Count() < 5)
        {
            return false;
        }
        QzModel qzModel = QzList.Last();// 获取最新落子点

        // 过滤无效棋子
        var QzList_Jc = QzList.Where(r =>
        (r.X + 8 <= qzModel.X || r.X - 8 <= qzModel.X)
        &&
        (r.Y - 5 <= qzModel.Y || r.Y + 5 <= qzModel.Y)).ToList();

        //当有效棋子数不够时不进行检测
        if (QzList_Jc.Count() <= 0)
        {
            return false;
        }


        // 竖向检测         
        // 按x坐标进行分组获取和落子点x坐标相同的棋子,进行竖向检测
        var QzList_jc = QzList_Jc.Where(r => r.X == qzModel.X).OrderByDescending(s => s.Y).ToList();

        for (int i = 0; i < QzList_jc.Count; i++)
        {
            // 防止下标溢出
            if (i + 1 >= QzList_jc.Count())
            {
                continue;
            }

            //检查棋子是否相连
            if (QzList_jc[i].Y == QzList_jc[i + 1].Y)
            {
                lx_number++;
            }
            else
            {
                lx_number = 0;
            }
            //相连棋子超过5或者等于5时判胜
            if (lx_number >= 5)
            {
                is_win = true;
            }
        }

        // 横向检测
        // 按y坐标进行分组获取和落子点y坐标相同的棋子,进行横向检测
        var QzList_jc_X = QzList_Jc.Where(r => r.Y == qzModel.Y).OrderByDescending(s => s.X).ToList();

        for (int i = 0; i < QzList_jc_X.Count; i++)
        {
            if (i + 1 >= QzList_jc_X.Count())
            {
                continue;
            }

            if (QzList_Jc[i].X == QzList_jc_X[i + 1].X + 2)
            {
                lx_number++;
            }
            else
            {
                lx_number = 0;
            }

            if (lx_number >= 5)
            {
                is_win = true;
            }

        }

        // 左斜向检测\
        for (int i = 0; i < 9; i++)
        {
            int x = 0;
            int y = 0;

            if (i < 4)
            {
                x = qzModel.X / 2 - (4 - i);
                y = qzModel.Y - (4 - i);
            }
            else if (i == 4)
            {
                x = qzModel.X / 2;
                x = qzModel.Y;
            }
            else
            {
                x = qzModel.X / 2 + (i - 4);
                x = qzModel.Y + (i - 4);
            }
            if (QzList_Jc.Where(r => r.X == x * 2 && r.Y == y).Count() == 1)
            {
                lx_number++;
            }
            else
            {
                lx_number = 0;
            }

            if (lx_number >= 5)
            {
                is_win = true;
            }
        }


        // 右斜向检测/
        for (int i = 0; i < 9; i++)
        {
            int x = 0;
            int y = 0;

            if (i < 4)
            {
                x = qzModel.X / 2 - (4 - i);
                y = qzModel.Y + (4 - i);
            }
            else if (i == 4)
            {
                x = qzModel.X / 2;
                x = qzModel.Y;
            }
            else
            {
                x = qzModel.X / 2 + (i - 4);
                x = qzModel.Y - (i - 4);
            }
            if (QzList_Jc.Where(r => r.X == x * 2 && r.Y == y).Count() == 1)
            {
                lx_number++;
            }
            else
            {
                lx_number = 0;
            }

            if (lx_number >= 5)
            {
                is_win = true;
            }
        }
        return is_win;
    }

    /// <summary>
    /// 按键检测光标移动
    /// </summary>
    /// <param name="key">按键值</param>
    public static bool DownKey(ConsoleKey key)
    {
        //检测按键,对不同按键进行不同操作
        switch (key)
        {
            // 光标上移
            case ConsoleKey.W:
            case ConsoleKey.UpArrow:
                index_Y -= 1;
                Console.SetCursorPosition(index_X, index_Y);
                break;
            // 光标左移
            case ConsoleKey.A:
            case ConsoleKey.LeftArrow:
                index_X -= 2;
                Console.SetCursorPosition(index_X, index_Y);
                break;
            // 光标下移
            case ConsoleKey.S:
            case ConsoleKey.DownArrow:
                index_Y += 1;
                Console.SetCursorPosition(index_X, index_Y);
                break;
            // 光标右移
            case ConsoleKey.D:
            case ConsoleKey.RightArrow:
                index_X += 2;
                Console.SetCursorPosition(index_X, index_Y);
                break;
            // 落子
            case ConsoleKey.Spacebar:
                //检测是否已经有棋子存在
                var count = QzList.Where(r => r.X == index_X && r.Y == index_Y).ToList().Count;
                if (count > 0)
                {
                    CzjlModel czjlModel = new CzjlModel()
                    {
                        Content = "此处已经有棋子了,请重新落子!",
                        Sort = QzList.Count + 1,
                    };
                    Czjl.Add(czjlModel);
                    Console.SetCursorPosition(0, 16);
                    if (type == 0)
                    {
                        Draw_Czjl("白子");
                    }
                    else
                    {
                        Draw_Czjl("黑子");
                    }
                    // 落子失败返回false,提示玩家重新落子
                    return false;
                }
                //生成对应棋子,添加到棋子集合
                if (type == 0)
                {
                    Console.Write("●");
                    QzModel qzModel = new QzModel()
                    {
                        Type = 0,
                        X = index_X,
                        Y = index_Y,
                    };
                    QzList.Add(qzModel);
                }
                else
                {
                    Console.Write("○");
                    QzModel qzModel = new QzModel()
                    {
                        Type = 1,
                        X = index_X,
                        Y = index_Y,
                    };
                    QzList.Add(qzModel);
                }
                Console.SetCursorPosition(0, 16);

                // 生成落子记录,添加到记录集合
                if (type == 0)
                {
                    CzjlModel czjlModel = new CzjlModel()
                    {
                        Content = "白棋在" + "[" + index_X / 2 + "," + index_Y + "] 处" + "落子",
                        Sort = QzList.Count + 1,
                    };
                    Czjl.Add(czjlModel);
                    Draw_Czjl("黑子");
                    type = 1;
                }
                else
                {
                    CzjlModel czjlModel = new CzjlModel()
                    {
                        Content = "黑棋在" + "[" + index_X / 2 + "," + index_Y + "] 处" + "落子",
                        Sort = QzList.Count + 1,
                    };
                    Czjl.Add(czjlModel);
                    Draw_Czjl("白子");
                    huihe++;
                    type = 0;
                }
                return true;
        }
        return false;
    }
}

/// <summary>
/// 操作记录model
/// </summary>
public class CzjlModel
{
    /// <summary>
    /// 内容
    /// </summary>
    public string Content { get; set; }

    /// <summary>
    /// 序号
    /// </summary>
    public int Sort { get; set; }
}

/// <summary>
/// 棋子model
/// </summary>
public class QzModel
{
    /// <summary>
    /// 棋子类型,0白棋1黑棋
    /// </summary>
    public int Type { get; set; }

    /// <summary>
    /// 棋子X坐标
    /// </summary>
    public int X { get; set; }

    /// <summary>
    /// 棋子Y坐标
    /// </summary>
    public int Y { get; set; }
}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值