关卡逻辑
while (pos[0] <= 99 && pos[1] <= 99)
上面条件存在bug,将判断循环的条件改为
while (pos[0] < 99 && pos[1] < 99)
各种类型的关卡的逻辑判断(关卡只判断一次)
1)判断两个玩家,谁踩到谁了,被踩到的玩家坐标为0
2)普通关卡 没有任何逻辑代码,在绘制地图方法中会将当前玩家替换掉普通关卡的图案
3)地雷关卡 因为是先投掷骰子后判断玩家当前坐标加骰子数后再判断关卡,一次有两种判断模式:1)在加上骰子数基础上-6 2)在减去骰子数基础上-6
switch-case结构中的一个
case 1://地雷(-6)
msg = string.Format("玩家{0}走到地雷关卡~@-_-@~,将要后退6格!!!", players[0]);
//模式1
//在减去骰子数的基础上后退6格关卡
//如果再次遇到关卡不再判断
pos[0] -= 6 - rdm;
//模式2
//在加上骰子数的基础上后退6格关卡
//如果再次遇到关卡不再判断
//骰子数在此判断结构之前已加上,然后-6
// pos[0] -= 6;
break;
4)暂停关卡 本游戏使用的是减去骰子数的方式;另一种是设置一个标志变量(默认值为false),如果遇到暂停关卡,标志变量为true,则跳过投掷骰子与各类型关卡的判断
case 2://暂停(0)
//减去增加的骰子数
pos[0] -= rdm;
msg = string.Format("玩家{0}走到暂停关卡~@-_-@~,需要休息一下!!!", players[0]);
break;
5)飞盘关卡 与地雷关卡类似有两种模式,只是飞盘是前进10格关卡
case 3://飞盘( 10)
msg = string.Format("玩家{0}走到飞盘关卡~@^_^@~,就要前进10格!!!", players[0]);
//在减去骰子数的基础前进格
pos[0] = 10 - rdm;
break;
整个游戏玩家遇到关卡的逻辑判断代码
class Program
{
//地图数组声明为 类的成员变量
//表示游戏中所有关卡的格子
static int[] levelData = new int[100];
//表示两个玩家在地图中的坐标(对应levelData中的下标)
//static int player1 = 0, player2=0;
//使用数组表示两个玩家的坐标
static int[] pos = new int[] { 0, 0 };
static string[] players = { "A", "B" };
//程序入口方法
static void Main(string[] args)
{
while (true)
{
ShowMapInfo();
InitData();
DrawMap();
//用于产生随机数
Random r = new Random();
int rdm = 0;//用于接收产生的随机数
//
while (pos[0] < 99 && pos[1] < 99)
{
//用于显示遇到的关卡信息
string msg = "";
#region 玩家A
Console.WriteLine("玩家A按任意键开始投掷骰子");
Console.ReadKey(true);//true 不显示所按的是什么键
rdm = r.Next(1, 7);//产生1-6之间任意的整数
Console.WriteLine("玩家A骰子数为{0}", rdm);
Console.WriteLine("按任意键玩家A开始行走");
Console.ReadKey(true);
//骰子数就是玩家A马上行走的关卡数
pos[0] = pos[0] rdm;
CheckPos();
if (pos[0] == pos[1])
{
pos[1] = 0;
msg = string.Format("玩家{0}踩到了玩家{1},玩家{2}从头开始", players[0], players[1], players[1]);
}
else
{
switch (levelData[pos[0]])
{
case 0://可有可无
//普通关卡,没有逻辑判断
//与default对应使用
break;
case 1://地雷(-6)
msg = string.Format("玩家{0}走到地雷关卡~@-_-@~,将要后退6格!!!", players[0]);
//在减去骰子数的基础上退6格
pos[0] -= 6 - rdm;
break;
case 2://暂停(0)
//减去增加的骰子数
pos[0] -= rdm;
msg = string.Format("玩家{0}走到暂停关卡~@-_-@~,需要休息一下!!!", players[0]);
break;
case 3://飞盘( 10)
msg = string.Format("玩家{0}走到飞盘关卡~@^_^@~,就要前进10格!!!", players[0]);
//在减去骰子数的基础前进格
pos[0] = 10 - rdm;
break;
default://防止意外数字(可有可无)
msg = "意外数字,不影响游戏运行";
break;
}
//检测玩家坐标是否在0-99之间
//主要是检测遇到地雷关卡
//地雷关卡会出现负数下标
CheckPos();
}
if (msg != "")
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(msg);
Console.ResetColor();
Console.ReadKey();
}
msg = "";
//清屏
Console.Clear();
//重新绘制地图
DrawMap();
#endregion
//如果玩家A或玩家B走到下标为99的关卡格子
//退出当前投掷骰子是循环
if (pos[0] == 99 || pos[1] == 99)
{
break;
}
//==================================
#region 玩家B
Console.WriteLine("玩家B按任意键开始投掷骰子");
Console.ReadKey(true);//true 不显示所按的是什么键
rdm = r.Next(1, 7);//产生1-6之间任意的整数
Console.WriteLine("玩家B骰子数为{0}", rdm);
Console.WriteLine("按任意键玩家B开始行走");
Console.ReadKey(true);
pos[1] = pos[1] rdm;
CheckPos();
if (pos[1] == pos[0])
{
pos[0] = 0;
msg = string.Format("玩家{0}踩到了玩家{1},玩家{2}从头开始", players[1], players[0], players[0]);
}
else
{
switch (levelData[pos[1]])
{
case 0://可有可无
//普通关卡,没有逻辑判断
//与default对应使用
break;
case 1://地雷(-6)
msg = string.Format("玩家{0}走到地雷关卡~@-_-@~,将要后退6格!!!", players[1]);
//在加上骰子数的基础上退6格
pos[1] -= 6;
break;
case 2://暂停(0)
//减去增加的骰子数
//相当于暂停一次
pos[1] -= rdm;
msg = string.Format("玩家{0}走到暂停关卡~@-_-@~,需要休息一下!!!", players[1]);
break;
case 3://飞盘( 10)
msg = string.Format("玩家{0}走到飞盘关卡~@^_^@~,就要前进10格!!!", players[1]);
//在加上骰子数的基础前进格
pos[1] = 10;
break;
default://防止意外数字(可有可无)
msg = "意外数字,不影响游戏运行";
break;
}
//检测玩家坐标是否在0-99之间
CheckPos();
}
if (msg != "")
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(msg);
Console.ResetColor();
Console.ReadKey();
}
//清屏
Console.Clear();
//重新绘制地图
DrawMap();
#endregion
}
if (pos[0] == 99)
{
Console.WriteLine("恭喜玩家A赢得胜利,按任意键重新开始下次游戏");
}
else
{
Console.WriteLine("恭喜玩家B赢得胜利,按任意键重新开始下次游戏");
}
//用于while(true)循环
//下次循环之前两个玩家坐标恢复为0
//否则就会陷入死循环
//玩家坐标等于99,条件一直成立
//不再进入投掷骰子的循环中
pos[0] = 0;
pos[1] = 0;
//程序暂停,显示玩家胜利信息
Console.ReadKey();
//清除之前的地图与投掷骰子的信息
Console.Clear();
}
}
#region 检测并限制玩家坐标必须在0-99
// 检测当前玩家坐标
static void CheckPos()
{
for (int i = 0; i < pos.Length; i )
{
//假设骰子数为3,地图中下标为3的是地雷
//按照规则退6步,玩家坐标就会变为-3
//因此需要限制玩家坐标在0-99
if (pos[i] < 0)
{
pos[i] = 0;
}
if (pos[i] > 99)
{
pos[i] = 99;
}
}
}
#endregion
#region 3 依据关卡数据绘制地图
static void DrawMap()
{
Console.WriteLine("● 地雷(-6) ▲ 暂停(0) ◎ 飞盘( 10)");
Console.WriteLine("");
Console.WriteLine("玩家A的坐标: {0}", pos[0]);
Console.WriteLine("玩家B的坐标: {0}", pos[1]);
#region 绘制第一横排30个关卡
//绘制第一横排30个关卡
for (int i = 0; i <= 29; i )
{
//string str = GetPattern(i);
//Console.Write(str);
//调用方法即可
Console.Write(GetPattern(i));
}
#endregion
//换行绘制竖排
Console.WriteLine("");
#region 绘制第一竖排5个关卡
for (int i = 30; i < 35; i )
{
//绘制竖排关卡前面的空格
////一个半角空格
//for (int j = 0; j < 58; j )
//{
// Console.Write(" ");
//}
//一个全角空格(就是两个半角空格)
for (int j = 0; j < 29; j )
{
Console.Write(" ");
}
//绘制关卡
Console.WriteLine(GetPattern(i));
}
#endregion
//绘制第二横排关卡
for (int i = 64; i >= 35; i--)
{
Console.Write(GetPattern(i));
}
//绘制第二竖排关卡
Console.WriteLine("");
for (int i = 65; i < 70; i )
{
Console.WriteLine(GetPattern(i));
}
//绘制第三横排
for (int i = 70; i < 100; i )
{
Console.Write(GetPattern(i));
}
//恢复默认颜色,否则下面再输入其他字符
//就会是之前最后设置的颜色
//Console.ResetColor();
//或者设置为
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("");
}
/// <summary>
/// 根据下标返回对应的关卡图案
/// </summary>
/// <param name="index">下标</param>
/// <returns>返回对应关卡图案</returns>
static string GetPattern(int index)
{
string strPt = "";
//判断两个玩家坐标是否相同
if (index == pos[0] && pos[0] == pos[1])
{
//设置输出字符时要显示的颜色
Console.ForegroundColor = ConsoleColor.Cyan;
strPt = "><";
}
//判断玩家A
else if (index == pos[0])
{
Console.ForegroundColor = ConsoleColor.Cyan;
strPt = "A";
}
//判断玩家B
else if (index == pos[1])
{
Console.ForegroundColor = ConsoleColor.Cyan;
strPt = "B";
}
//排除前面条件后判断各类型关卡
else
{
//判断各类型关卡
switch (levelData[index])
{
//普通关卡
case 0:
Console.ForegroundColor = ConsoleColor.White;
strPt = "□";
break;
//地雷关卡
case 1:
Console.ForegroundColor = ConsoleColor.Red;
strPt = "●";
break;
//暂停关卡
case 2:
Console.ForegroundColor = ConsoleColor.Yellow;
strPt = "▲";
break;
//飞盘关卡
case 3:
Console.ForegroundColor = ConsoleColor.DarkGreen;
strPt = "◎";
break;
//防止意外数据(可以忽略不要)
default:
Console.ForegroundColor = ConsoleColor.White;
strPt = "□";
break;
}
}
return strPt;
}
#endregion
#region 2 手动初始化关卡数据
//初始化地图关卡数据
static void InitData()
{
//●表示地雷 设置元素值为 1
int[] mine = { 3, 23, 35, 47, 52, 66, 79, 82, 93 };
//▲表示暂停 设置元素值为 2
int[] suspend = { 7, 26, 55, 69, 88 };
//◎表示飞盘 设置元素值为 3
int[] frisbee = { 9, 33, 59, 85 };
for (int i = 0; i < mine.Length; i )
{
//int a=mine[i];
//chequer[a]=1;
//等同于下面
levelData[mine[i]] = 1;
}
for (int i = 0; i < suspend.Length; i )
{
levelData[suspend[i]] = 2;
}
for (int i = 0; i < frisbee.Length; i )
{
levelData[frisbee[i]] = 3;
}
}
#endregion
#region 1 显示游戏信息
//显示游戏信息
static void ShowMapInfo()
{
string title = "飞行棋小游戏 1.0";
Console.Title = title;
Console.WriteLine("\t\t\t***************************");
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("\t\t\t* " title " *");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("\t\t\t***************************");
Console.WriteLine("\t\t\t\t飞行棋游戏规则");
Console.WriteLine("\t\t\t●地雷(-6) ▲暂停(0) ◎飞盘( 10)");
Console.WriteLine("");
}
#endregion
}
上面玩家A,B遇到关卡的逻辑判断代码90%以上都一样,有许多的冗余代码,因此将其提取为一个方法,方法只需传入当前玩家即可
static void Main(string[] args)
{
while (true)
{
ShowMapInfo();
InitData();
DrawMap();
//任意玩家坐标没有到达99
//进入循环依次投掷骰子
while (pos[0] <= 99 && pos[1] <= 99)
{
//用于判断玩家A
CheckLeve(0);
//判断有任意玩家坐标到达99
//退出投掷骰子的循环
if (pos[0] == 99 || pos[1] == 99)
{
break;
}
//==================================
//判断玩家B
CheckLeve(1);
}
//退出投掷骰子的循环
//判断哪个玩家赢得胜利
if (pos[0] == 99)
{
Console.WriteLine("恭喜玩家A赢得胜利,按任意键重新开始下次游戏");
}
else
{
Console.WriteLine("恭喜玩家B赢得胜利,按任意键重新开始下次游戏");
}
//玩家A,B坐标重置,游戏重新开始运行
pos[0] = 0;
pos[1] = 0;
Console.ReadKey();
Console.Clear();
}
}
//检测当前玩家遇到关卡的逻辑判断
static void CheckLeve(int curIndex)
{
Random r = new Random();
int rdm = 0;//用于接收产生的随机数
string msg = "";//用于显示关卡信息
Console.WriteLine("玩家{0}按任意键开始投掷骰子", players[curIndex]);
Console.ReadKey(true);//true 不显示所按的是什么键
rdm = r.Next(1, 7);//产生1-6之间任意的整数
Console.WriteLine("玩家{0}骰子数为{1}", players[curIndex], rdm);
Console.WriteLine("按任意键玩家{0}开始行走", players[curIndex]);
Console.ReadKey(true);
//骰子数就是当前玩家马上行走的关卡数
pos[curIndex] = pos[curIndex] rdm;
CheckPos();
if (pos[0] == pos[1])
{
//如果是玩家A 玩家B回到起点
//如果是玩家B 玩家A回到起点
pos[1 - curIndex] = 0;
msg = string.Format("玩家{0}踩到了玩家{1},玩家{2}从头开始", players[curIndex], players[1 - curIndex], player
curIndex]);
}
else
{
switch (levelData[pos[curIndex]])
{
case 0://可有可无
//普通关卡,没有逻辑判断
//与default对应使用
break;
case 1://地雷(-6)
msg = string.Format("玩家{0}走到地雷关卡~@-_-@~,将要后退6格!!!", players[curIndex]);
//在加上骰子数的基础上退6格
pos[curIndex] -= 6;
break;
case 2://暂停(0)
//减去增加的骰子数
pos[curIndex] -= rdm;
msg = string.Format("玩家{0}走到暂停关卡~@-_-@~,需要休息一下!!!", players[curIndex]);
break;
case 3://飞盘( 10)
msg = string.Format("玩家{0}走到飞盘关卡~@^_^@~,就要前进10格!!!", players[curIndex]);
////在加上骰子数的基础前进格
//pos[curPos] = 10;
//在减去骰子数的基础前进格
pos[curIndex] = 10 - rdm;
break;
default://防止意外数字(可有可无)
msg = "意外数字,不影响游戏运行";
break;
}
//检测玩家坐标是否在0-99之间
CheckPos();
}
if (msg != "")
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(msg);
Console.ResetColor();
Console.ReadKey();
}
//清屏
Console.Clear();
//重新绘制地图
DrawMap();
}
玩家A投掷骰子后必须判断两个玩家坐标是否达到99,如果玩家A被玩家B踩到,就有可能玩家B先达到条件,赢得比赛;如果只判断A,就不会退出投掷骰子的循环
玩家B坐标先达到99,赢得胜利