欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【人机交互实验】命令行数独游戏 C#

程序员文章站 2022-06-04 16:12:26
...

题目

a) 设计一个命令行界面的游戏,登入游戏界面后,应该有游戏规则说明,按键说明。
b) 进入游戏前应该有难度选择:1表示简单、2表示中等、3表示困难。
c) 在游戏主界面中有可以循环输入数独值、可以连续玩好几局直到退出、检查结果、查看答案、新开一局的功能。
d) 信息提示功能:输入错误时应有提示、游戏失败或获取胜利时应有庆祝界面等。

展示

【人机交互实验】命令行数独游戏 C#
【人机交互实验】命令行数独游戏 C#

源码

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  
  
namespace Jiaohu1  
{  
    class Sdnum  
    {  
        public int num;  
        public ConsoleColor c;  
  
        public Sdnum(int x = 0, ConsoleColor col = ConsoleColor.White)  
        {  
            num = x;  
            c = col;  
        }  
        public void ChangeColor(ConsoleColor col)  
        {  
            c = col;  
        }  
        public void ChangeNum(int n)  
        {  
            num = n;  
        }  
        public void Display()  
        {  
            if (c != ConsoleColor.White)  
                Console.ForegroundColor = c;  
            Console.Write(" ");  
            if (num >= 1 && num <= 9)  
                Console.Write(num);  
            else if (num == 0)  
                Console.Write(" ");  
            else if (num == 10)  
                Console.Write("x");  
            if (c != ConsoleColor.White)  
                Console.ForegroundColor = ConsoleColor.White;  
            Console.Write(" ");  
        }  
    }  
    class Line  
    {  
        string s;  
  
        public Line(string line)  
        {  
            s = line;  
        }  
        public void Display(ConsoleColor col)  
        {  
            Console.ForegroundColor = col;  
            Console.Write(s);  
            Console.ForegroundColor = ConsoleColor.White;  
        }  
        public void Display2()  
        {  
            Console.ForegroundColor = ConsoleColor.Blue;  
            Console.Write(s.Substring(0, 1));  
            Console.ForegroundColor = ConsoleColor.White;  
            Console.Write(s.Substring(1, 11));  
            Console.ForegroundColor = ConsoleColor.Blue;  
            Console.Write(s.Substring(12, 1));  
            Console.ForegroundColor = ConsoleColor.White;  
            Console.Write(s.Substring(13, 11));  
            Console.ForegroundColor = ConsoleColor.Blue;  
            Console.Write(s.Substring(24, 1));  
            Console.ForegroundColor = ConsoleColor.White;  
            Console.Write(s.Substring(25, 11));  
            Console.ForegroundColor = ConsoleColor.Blue;  
            Console.Write(s.Substring(36, 1));  
            Console.ForegroundColor = ConsoleColor.White;  
        }  
    }  
    class Menu  
    {  
        int choose, type, top_ch;  
        List<string> c = new List<string>();  
        string top;  
        string left, right;  
        string blank;  
        string bottom;  
  
        public Menu(int menuType)  
        {  
            type = menuType;  
        }  
        public void Init1()  
        {  
            choose = 0;  
            c.Add("a--进入数独游戏");  
            c.Add("b--游戏规则说明");  
            c.Add("c--按键说明");  
            c.Add("e--退出游戏");  
            top = "********欢迎进入数独游戏********";  
            top_ch = 8;  
            left = "<<      ";  
            right = ">>";  
            blank = "<<                            >>";  
            bottom = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";  
        }  
        public void Init2()  
        {  
            choose = -1;  
            c.Add("数独游戏在9×9的方格内进行,分为3×3的小方格,被称为区.");  
            c.Add("数独游戏首先从已经填入数字的格子开始.");  
            c.Add("用1至9之间的数字填满空格,一个格子只能填入一个数字.");  
            c.Add("每个数字在每一行只能出现一次;");  
            c.Add("每个数字在每一列只能出现一次;");  
            c.Add("每个数字在每一区只能出现一次;");  
            c.Add("总结这些规则,即每个数字在每一行,每一列和每一区只能出现一次.");  
            top = "*****************************数独游戏规则******************************";  
            top_ch = 6;  
            left = "<<    ";  
            right = ">>";  
            blank = "<<                                                                   >>";  
            bottom = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";  
        }  
        public void Init3()  
        {  
            choose = -1;  
            c.Add("进入游戏后要输入3个数:所在行、所在列、其值.");  
            c.Add("            3个数分别用空格隔开.");  
            c.Add("           输完后用回车键进行确定.");  
            top = "*************************数独游戏按键说明*************************";  
            top_ch = 8;  
            left = "<<        ";  
            right = ">>";  
            blank = "<<                                                              >>";  
            bottom = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";  
        }  
        public void Init4()  
        {  
            choose = 0;  
            c.Add("a--简单");  
            c.Add("b--中等");  
            c.Add("c--困难");  
            c.Add("e--返回");  
            top = "************游戏难度选择************";  
            top_ch = 6;  
            left = "<<             ";  
            right = ">>";  
            blank = "<<                                >>";  
            bottom = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";  
  
        }  
        public void Init5()  
        {  
            choose = -1;  
            c.Add("    恭喜!");  
            c.Add("   你答对了");  
            c.Add(" 你真是个天才");  
            top = "**************庆祝**************";  
            top_ch = 2;  
            left = "<<        ";  
            right = ">>";  
            blank = "<<                            >>";  
            bottom = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";  
        }  
  
        public void Display()  
        {  
            Console.Clear();  
            int cleft = Math.Min(Math.Max((Console.WindowWidth - top.Length) / 2, 0), Console.WindowWidth - 1);  
            int ctop = Math.Min(Math.Max((Console.WindowHeight - c.Count - 7) / 2, 0), Console.WindowWidth - 1);  
            Console.SetCursorPosition(cleft, ctop++);  
            Console.WriteLine(top);  
            Console.SetCursorPosition(cleft, ctop++);  
            Console.WriteLine(blank);  
            Console.SetCursorPosition(cleft, ctop++);  
            Console.WriteLine(blank);  
            for (int i = 0; i < c.Count; i++)  
            {  
                Console.SetCursorPosition(cleft, ctop++);  
                Console.Write(left);  
                if (choose == i)  
                {  
                    Console.ForegroundColor = ConsoleColor.Yellow;  
                    Console.Write(c[i]);  
                    Console.ForegroundColor = ConsoleColor.White;  
                }  
                else  
                {  
                    Console.Write(c[i]);  
                }  
                Console.SetCursorPosition(Math.Min(Math.Max(cleft + top.Length - 2 + top_ch, 0), Console.WindowWidth - 1), ctop - 1);  
                Console.WriteLine(right);  
            }  
            Console.SetCursorPosition(cleft, ctop++);  
            Console.WriteLine(blank);  
            Console.SetCursorPosition(cleft, ctop++);  
            Console.WriteLine(blank);  
            Console.SetCursorPosition(cleft, ctop++);  
            Console.WriteLine(bottom);  
            Console.SetCursorPosition(Math.Min(Math.Max((Console.WindowWidth - 10) / 2, 0), Console.WindowWidth - 1), ctop++);  
            Console.WriteLine("按Enter键继续...");  
        }  
        void Up()  
        {  
            choose -= 1;  
            if (choose == -1)  
                choose = c.Count - 1;  
        }  
        void Down()  
        {  
            choose += 1;  
            if (choose == c.Count)  
                choose = 0;  
        }  
        public int Listen()  
        {  
            ConsoleKeyInfo cki;  
            do  
            {  
                cki = Console.ReadKey();  
                if (type == 1)  
                {  
                    switch (cki.Key.ToString())  
                    {  
                        case "UpArrow":  
                            Up();  
                            break;  
                        case "DownArrow":  
                            Down();  
                            break;  
                        case "A":  
                            choose = 0;  
                            break;  
                        case "B":  
                            choose = 1;  
                            break;  
                        case "C":  
                            choose = 2;  
                            break;  
                        case "E":  
                            choose = 3;  
                            break;  
                    }  
                    Display();  
                }  
            } while (cki.Key != ConsoleKey.Enter);  
            return choose;  
        }  
    }  
    class Sudoku  
    {  
        List<Sdnum> map = new List<Sdnum>();  
        Line headLine = new Line("┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┳━━━┓");  
        Line normalLine = new Line("┣━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━╋━━━┫");  
        Line bottomLine = new Line("┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┻━━━┛");  
        int[] solution = new int[81]  
        {  
            2,1,6,4,8,9,7,5,3,  
            4,3,8,5,6,7,2,1,9,  
            7,9,5,1,3,2,8,6,4,  
            1,8,9,3,7,5,4,2,6,  
            3,2,4,6,1,8,9,7,5,  
            6,5,7,2,9,4,3,8,1,  
            8,6,2,9,4,1,5,3,7,  
            9,7,3,8,5,6,1,4,2,  
            5,4,1,7,2,3,6,9,8  
        };  
        int[] save = new int[81];  
        int choose,diff,left,top;  
  
        public void Init(int difficulty)  
        {  
            choose = -1;  
            diff = difficulty;  
            map.Clear();  
            for (int i = 0; i < 81; i++)  
            {  
                map.Add(new Sdnum());  
                save[i] = 0;  
            }  
            Random ran = new Random();  
            List<int> temp = new List<int>();  
            int k;  
            for (int i = 0; i < 81; i++)  
                temp.Add(i);  
            for (int i = 0; i < difficulty; i++)  
            {  
                k = ran.Next(0, temp.Count);  
  
                save[temp[k]] = 1;  
                map[temp[k]].ChangeNum(solution[temp[k]]);  
                temp.RemoveAt(k);  
            }  
            for (int i = 0; i < 81; i++)  
            {  
                if (save[i] != 1)  
                {  
                    map[i].ChangeColor(ConsoleColor.Green);  
                }  
            }  
        }  
        void DisplayNumLine(int line)  
        {  
            int start = line * 9;  
            Console.ForegroundColor = ConsoleColor.Blue;  
            Console.Write("┃");  
            Console.ForegroundColor = ConsoleColor.White;  
            for (int i = 0; i < 9; i++)  
            {  
                map[start + i].Display();  
                if (i == 2 || i == 5 || i == 8)  
                {  
                    Console.ForegroundColor = ConsoleColor.Blue;  
                    Console.Write("┃");  
                    Console.ForegroundColor = ConsoleColor.White;  
                }  
                else  
                    Console.Write("┃");  
            }  
        }  
        public void DisplayMenu()  
        {  
            Console.Clear();  
            List<string> c = new List<string>();  
            int top = 6;  
            c.Add("a--输入指定位置");  
            c.Add("b--检查结果");  
            c.Add("c--查看答案");  
            c.Add("d--再来一局");  
            c.Add("e--返回");  
            for (int i = 0; i < c.Count; i++)  
            {  
                Console.SetCursorPosition(5, top);  
                top += 2;  
                if (choose == i)  
                    Console.ForegroundColor = ConsoleColor.Yellow;  
                Console.Write(c[i]);  
                if (choose == i)  
                    Console.ForegroundColor = ConsoleColor.White;  
            }  
        }  
        public void Display()  
        {  
            left = (Console.WindowWidth - 40) / 2;  
            top = 0;  
            Console.SetCursorPosition(left + 2, top++);  
            Console.WriteLine("1   2   3   4   5   6   7   8   9");  
            Console.SetCursorPosition(left, top++);  
            headLine.Display(ConsoleColor.Blue);  
            for (int i = 0; i < 8; i++)  
            {  
                Console.SetCursorPosition(left - 1, top++);  
                Console.Write(i + 1);  
                DisplayNumLine(i);  
                Console.SetCursorPosition(left, top++);  
                if ((i + 1) % 3 == 0)  
                    normalLine.Display(ConsoleColor.Blue);  
                else  
                    normalLine.Display2();  
            }  
            Console.SetCursorPosition(left - 1, top++);  
            Console.Write(9);  
            DisplayNumLine(8);  
            Console.SetCursorPosition(left, top++);  
            bottomLine.Display(ConsoleColor.Blue);  
            Console.WriteLine();  
        }  
        void DisplaySolution()  
        {  
            Sudoku temp = new Sudoku();  
            temp.Init(81);  
            Console.Clear();  
            temp.Display();  
            Console.SetCursorPosition(left, top++);  
            Console.Write("按任意键继续...");  
            Console.ReadKey();  
        }  
        void CheckOut()  
        {  
            bool isOK=true;  
            DisplayMenu();  
            Display();  
            for(int i = 0; i < 81; i++)  
            {  
                if (map[i].num < 1 || map[i].num > 9 || (save[i] == 0 && map[i].c == ConsoleColor.Red))   
                {  
                    isOK = false;  
                    Console.SetCursorPosition(left, top++);  
                    Console.Write("对不起,你的答案不正确,请再检查一下!");  
                    Console.SetCursorPosition(left, top++);  
                    Console.Write("按Enter键继续...");  
                    break;  
                }  
            }  
            if (isOK)  
            {  
                Console.Clear();  
                Menu cele=new Menu(2);  
                cele.Init5();  
                cele.Display();  
            }  
            ConsoleKeyInfo cki;  
            do  
            {  
                cki = Console.ReadKey();  
            } while (cki.Key != ConsoleKey.Enter);  
        }  
        bool isRepeat(int i,int j,int k)  
        {  
            for (int m = 0; m < 9; m++)  
                if (map[m * 9 + j].num == k && m != i)  
                    return true;  
            for (int n = 0; n < 9; n++)  
                if (map[i * 9 + n].num == k && n != j)  
                    return true;  
            for (int p = (i / 3) * 3; p < (i / 3) * 3 + 3; p++)  
                for (int q = (j / 3) * 3; q < (j / 3) * 3 + 3; q++)   
                    if (map[p * 9 + q].num == k && p != i && q != j)  
                        return true;  
            return false;  
        }  
        void InputNum()  
        {  
            int i, j, k;  
            char temp;  
            DisplayMenu();  
            Display();  
            Console.SetCursorPosition(left, top++);  
            Console.Write("选择行号:");  
            temp = Console.ReadKey().KeyChar;  
            if (temp >= '1' && temp <= '9')  
                i = temp-'0';  
            else  
            {  
                Console.SetCursorPosition(left, top++);  
                Console.Write("非法的行号,应该输入1~9的数字");  
                Console.SetCursorPosition(left, top++);  
                Console.Write("请按任意键继续...");  
                Console.ReadKey();  
                InputNum();  
                return;  
            }  
            Console.Write("   列号:");  
            temp = Console.ReadKey().KeyChar;  
            if (temp >= '1' && temp <= '9')  
                j = temp - '0';  
            else  
            {  
                Console.SetCursorPosition(left, top++);  
                Console.Write("非法的列号,应该输入1~9的数字");  
                Console.SetCursorPosition(left, top++);  
                Console.Write("请按任意键继续...");  
                Console.ReadKey();  
                InputNum();  
                return;  
            }  
            int n = (i - 1) * 9 + j-1;  
            if (save[n] == 1)  
            {  
                Console.SetCursorPosition(left, top++);  
                Console.Write("对不起,原题中该位置已经指定为"+map[n].num+",你不能修改这个值");  
                Console.SetCursorPosition(left, top++);  
                Console.Write("请按任意键继续...");  
                Console.ReadKey();  
                InputNum();  
                return;  
            }  
            Console.Write("   填入的值:");  
            temp = Console.ReadKey().KeyChar;  
            if (temp >= '1' && temp <= '9')  
                k = temp - '0';  
            else  
            {  
                Console.SetCursorPosition(left, top++);  
                Console.Write("非法的值,应该输入1~9的数字");  
                Console.SetCursorPosition(left, top++);  
                Console.Write("请按任意键继续...");  
                Console.ReadKey();  
                InputNum();  
                return;  
            }  
            choose = -1;  
            map[n].ChangeNum(k);  
            if (isRepeat(i-1,j-1,k))  
            {  
                map[n].ChangeColor(ConsoleColor.Red);  
            }  
            else  
                map[n].ChangeColor(ConsoleColor.Green);  
            DisplayMenu();  
            Display();  
            Console.SetCursorPosition(left, top++);  
            Console.Write("填入成功");  
            Console.SetCursorPosition(left, top++);  
            Console.Write("请按任意键继续...");  
            for(int x = 0; x < 81; x++)  
            {  
                if (save[x] == 0)  
                    if (isRepeat(x / 9, x % 9, map[x].num))  
                        map[x].ChangeColor(ConsoleColor.Red);  
                    else map[x].ChangeColor(ConsoleColor.Green);  
            }  
            Console.ReadKey();  
            DisplayMenu();  
            Display();  
        }  
        void QuickMode()  
        {  
              
        }  
        public int Listen()  
        {  
            ConsoleKeyInfo cki;  
            do  
            {  
                cki = Console.ReadKey();  
                switch (cki.Key.ToString())  
                {  
                    case "A":  
                        choose = 0;  
                        InputNum();  
                        break;  
                    case "B":  
                        choose = 1;  
                        CheckOut();  
                        choose = -1;  
                        DisplayMenu();  
                        Display();  
                        break;  
                    case "C":  
                        choose = 2;  
                        DisplaySolution();  
                        choose = -1;  
                        DisplayMenu();  
                        Display();  
                        break;  
                    case "D":  
                        choose = 3;  
                        Init(diff);  
                        DisplayMenu();  
                        Display();  
                        break;  
                    case "E":  
                        choose = 5;  
                        return -1;  
                    default:  
                        DisplayMenu();  
                        Display();  
                        break;  
                }  
            } while (true);  
        }  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Sudoku sudoku = new Sudoku();  
            Menu startMenu = new Menu(1);  
            Menu rule = new Menu(2);  
            Menu Instr = new Menu(2);  
            Menu difficulty = new Menu(1);  
            startMenu.Init1();  
            rule.Init2();  
            Instr.Init3();  
            difficulty.Init4();  
            startMenu.Display();  
            int choose;  
            choose = startMenu.Listen();  
            do  
            {  
                switch (choose)  
                {  
                    case 0:  
                        difficulty.Display();  
                        choose = difficulty.Listen() + 4;  
                        break;  
                    case 1:  
                        rule.Display();  
                        choose = rule.Listen();  
                        break;  
                    case 2:  
                        Instr.Display();  
                        choose = Instr.Listen();  
                        break;  
                    case 3:  
                        return;  
                    case -1:  
                    case 7:  
                        startMenu.Display();  
                        choose = startMenu.Listen();  
                        break;  
                    case 4:  
                    case 5:  
                    case 6:  
                        sudoku.Init(81 - ((choose - 3) * 20));  
                        sudoku.DisplayMenu();  
                        sudoku.Display();  
                        choose = sudoku.Listen();  
                        break;  
                }  
            } while (choose != 3);  
        }  
    }  
}  

相关标签: 实验课