您的位置:首页 > 职场人生

黑马程序员 自学16C#编程基础之飞行棋

2014-04-22 10:49 302 查看
-------
Windows Phone 7手机开发、.Net培训、期待与您交流! -------





飞行棋练习:

2014/4/11/12/13/14

在开始之前,一些需要注意的情况:

1. 玩家姓名不能为空。玩家不能重名。

2. 地雷:退后N格。幸运轮盘:用户选择交换位置/轰炸。

3. 暂停。时空隧道:前进N格。

4. 不考虑用户循环踩到陷阱的情况,谁先走到头谁就赢,不考虑后退。

5. 谁踩到谁,被踩到的就回老家(判断方法:谁刚刚行动了就算谁踩到的)。

6. 通过时光隧道不算,因为奖惩机制一回合只一次。

7. 可以设置一系列特殊按键制造“后门”(作弊)。

8. 界面可以写在单独的方法中,用多功能块来做。Show UI(“”);显示界面

9. 用数组存储玩家姓名。第二个人既不能为空,也不能重。

输入姓名不能为空(while循环)

10. Console→控制控制台的方法。

11. 养成良好的学习方法,借助MSDN。

地图

用int类型,初始化0→“□”(最多的那个)

(int[]map= new int[100])(地图一百格)

1. 幸运:交换位置/退N格

2. 地雷:★

3. 暂停:▲

4. 隧道:卍

5. 普通:□

Int[]LuckyTurn={6,23,40,55,69,83};

★={5,13,17,33,38,50,64,80,94}

▲={9,27,60,93}

卍={20,25,45,63,72,88,90}

把特殊int值进行数组填加,在Map中填入特殊成员的值。

int number=LuckyTurn[i]; 取值,值就是Map数组中的一个个位置

map[number]=1; 把位置=0变成特殊值”1”~”5”;



map[LuckyTurn[i]]=1;

格数图:

|←———30个格——→|—



|

5个格

|



—|—————30—————



|

5个格

|



—|←————30————→|

(文字版):

从i=0:第?格

0 ~~~ 29
=横30格

30

~ =竖5格

34

64 ~~~ 35 =横30格

65

~ =竖5格

69 70 ~~~ 99 =横30格

Static void DrawMap()

先考虑用户的棋子是否在正要画的格上,playerPos[0]存A的下标,playerPos[1]存B的下标。

定义两个变量存储AB的坐标→Main方法外:static int[]playerPos={0,0};

playerPos[0]=A;

playerPos[1]=B;

符号为全角。

属性:BackgroundColor:背景色

方法:RestColor:颜色恢复默认

属性:ForegroundColor:前景色

属性:通过 =
对它进行赋值/取值。属性相当于一个变量。方法:在最后加();
用来调用。

颜色改变,绘制完成后要恢复颜色:

Console.ResetColor();

Console.ForegroundColor=Console.White;

这两个作用最后的效果是一样的。

掷骰子:

循环:

循环条件是?循环体?开始和结束的判断?

循环让玩家A和B轮流掷骰子,当A/B>=99,游戏结束。

方法:

ReadKey();

ReadKey(boolean);

↑确定是否在控制台窗口中显示按下的键,true表示不显示按下的键,false为显示。

产生随机数的两句话:

Rendom r=new Random();

Int i= r.Next(1,2);(1<=r<2)

(1.7)→1~6

产生一个m到n之间的随机数:Randomr= new Random(); int i= r.Next(m,n+1);

新坐标:playerPos[0]=playerPos[0]+step;(step = r)

if(playerPos[0]>99)

playerPos[0]=99;

DrawMap();→重绘地图,让A,B开始走动。

检测A/B是否走入特殊位置,只需要检测其中的值,不需要对应各特殊位置的数组了。(switch-case)

特殊位置的数组与Map数组的联系是靠值来维系的:

Map[LuckyChoice[i]]=1;

[boom[i]]=2; 我们若想调用特殊位置,

[pause[i]]=3; 就用Map[i]=的值来作为响应。

[through[i]]=4;

如果对一个string类型的变量进行赋值,需要使用占位符来让这个字符串内包含变量的话,可以这样做:

eg:mag=string . Format(“×{0}×{1}”, ××, ××) 类型 . 方法名

制造后门:

ConsoleKeyInfo(控制台的按键信息)rec =Console.ReadKey(ture);

If(rec.Key=ConsoleKey.Tab)

{

i=20

}

else

……

rec.Key=用户按下的键

Console.Tab=设置的按键Tab

ConsoleKeyInfo方法内有ConsoleKey→枚举属性,通过用户按下的键返回一个值。

其他按键:

ConsoleKeyInfo rec=Console.ReadKey(true);

If(rec.Key=ConsoleKey.Tab&&rec.Modifiers==ConsoleModifiers.Control)//按下Ctrl+Tab

rec.Key==ConsoleKey.Tab&&rec.Modifiers==(ConsoleModifiers.Control|ConsoleModifiers.Shift)

Tab+(Ctrl+Shift)

组合键只能是上面三个按键的搭配。

暂停:

A—→F—(有暂停)→T

B—→F—(有暂停)→T

所以若为F,下一回合可以掷骰子;

为T,下一回合不掷骰子。

定义一个数组:

Bool[]isStop={false,false}; isStop[0]表示A是否上一次走到了暂停;

isStop[1]表示B …………………………;

若走到暂停,则设置其值为true。

词汇小结:

Initial: 最初的

Choice: 选择

Pause: 暂停

Through: 通过

Foreground:前景

Reset: 重置

Dice: 掷骰子

Limit: 限制

练习:

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

namespace _20自学第二十天
{
class Program
{
static int[] map = new int[100];//方法都调用这个地图和玩家扔的骰子,所以定义在类下
static int[] player = { 0,0 };//默认AB开始同一位置,采用数组方式定义在类中,方便后面的赋值
static string[] playName = new string[2];
static Random r = new Random();//这个是生成随机数的方法。
static bool[] isStop = { false, false };//这个是为了暂停的判断。有两个程序Dice,bigin()调用

/// <summary>
/// 这个方法,来安排各个功能块的调用,此方法作用只到开始掷骰子时,后面的无效。
/// </summary>
/// <param name="args"></param>
private static void Main(string[] args)
{
ShowUI();
//采用数组来收集玩家姓名,为后面的调用后期的修改提供变量与便利。
Console.WriteLine("请输入两个玩家的姓名");
//开始输入两个玩家姓名,进行循环验证,不能重名不能为空
for (int i = 0; i < 2; i++)
{
Console.Write("第{0}位玩家名字:", i + 1);
playName[i] = Console.ReadLine();
if (playName[i] == "")
{
i--;
Console.WriteLine("名字不能为空,请重新输入");
//continue;
}
else if (i >= 1 && playName[i] == playName[i - 1])
{
i--;
Console.WriteLine("你输入的名字已存在,请重新输入");
}
}
Console.Clear();
Console.WriteLine("第一位玩家A:{0}\n第二位玩家B:{1}", playName[0], playName[1]);
Console.WriteLine("如果A与B在同一位置,则表示为<>");

InitialMap();//把特殊位置的数填入地图数组中,即为赋值。
Drawmap();//开始画地图,先考虑AB的位置,再考虑特殊位置,最后剩下的就是普通的
Console.WriteLine("game begin!");
//bool[] isStop = { false, false };
Dice(isStop);//开始掷骰子,传参isStop用来判断是否暂停。

Console.ReadKey();
}

/// <summary>
/// 这个方法显示开头的程序图案
/// </summary>
public static void ShowUI()
{
Console.WriteLine("###################################################");
Console.WriteLine("#                                                 #");
Console.WriteLine("#               骑   士  飞  行  棋               #");
Console.WriteLine("#                                                 #");
Console.WriteLine("###################################################");
}

/// <summary>
/// 这个方法是用来向map数组中填特殊成员的数值
/// </summary>
public static void InitialMap()
{
int[]luckyChoice = { 6, 23, 40, 55, 69, 83 };
for (int i = 0; i < luckyChoice.Length; i++)
{
map[luckyChoice[i]] = 1;
}
int[] boom = { 5, 13, 17, 33, 38, 50, 64, 80, 94 };
for (int i = 0; i < boom.Length; i++)
{
map[boom[i]] = 2;
}
int[] pause={9,27,60,93};
for (int i = 0; i < pause.Length; i++)
{
map[pause[i]] = 3;
}
int[] through = { 20, 25, 45, 63, 72, 88, 90};
for (int i = 0; i < through.Length; i++)
{
map[through[i]] = 4;
}
}

/// <summary>
/// 这个方法是用来绘制地图的,逐行循环输出。先考虑玩家位置,再特殊位置,再显示.
/// 内部还嵌套调用了一个判断该位置为何的方法。
/// </summary>
public static void Drawmap()
{//注意,一行三十个,从0~29是二十九个28+1
int i;//定义数组中元素的循环到的个数,对应着map数组中的元素
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("<>");
Console.ResetColor();
Console.Write(":两个棋子在同一位置上");
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("  A/B");
Console.ResetColor();
Console.Write(":你的棋子");
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write("\n◎");
Console.ResetColor();
Console.Write(":幸运抉择");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("  ☆");
Console.ResetColor();
Console.Write(":地雷");
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write("  ▲");
Console.ResetColor();
Console.Write(":暂停一回合");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("  卍");
Console.ResetColor();
Console.Write(":时空隧道");
Console.WriteLine();
for (i=0; i <29; i++)//第一行0~28 正序
{
ForJudge(ref i);
}
for (i =29; i < 35; i++)//29+换行+右侧第一列 30~34
{
ForJudge(ref i);
if (i == 34)
break;
Console.Write("\n");//这个换行是为了开始下面列的输出

for (int n = 0; n < 29; n++)
{
Console.Write(" ");
}
}
//下面这个代表换行,从头开始倒序输入。
Console.WriteLine("");
for (i =64; i>34; i--)
{
ForJudge(ref i);
}
Console.WriteLine("");//换行开始左列输出65~69
for (i = 65; i < 70; i++)
{
ForJudge(ref i);
if (i == 69)
break;
for (int n = 0; n < 29; n++)
{
Console.Write(" ");
}
Console.Write("\n");//循环换行显示下列第一个
}
Console.WriteLine("");//换行开始最后一行的输出,70~99
for (i = 70; i < 100; i++)
{
ForJudge(ref i);
}
Console.ResetColor();//Console.ForeqroundColor=ConsoleColor.White 还原颜色,否则后面所有文字都是最后一个图案的颜色
Console.WriteLine("");//最后换行开始输入数字
}

/// <summary>
/// 此方法用了ref传参来接收i的位置,从而判断该位置显示什么。
/// </summary>
/// <param name="i">i是当前的位置序数</param>
public static void ForJudge(ref int i)
{
if (player[0] == i && player[1] == i)
{
Console.ForegroundColor=ConsoleColor.Cyan;
Console.Write("<>");//注意使用全角符号
}
else if (player[0] == i)
{
Console.ForegroundColor=ConsoleColor.Cyan;
Console.Write("A");
}
else if (player[1] == i)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("B");

}
else
{
switch (map[i])
{
case 0:
Console.ForegroundColor=ConsoleColor.White;
Console.Write("□");
break;
case 1:
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write("◎");
break;
case 2:
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("★");
break;
case 3:
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write("▲");
break;
case 4:
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("卍");
break;

}
}

}

/// <summary>
/// 这个方法是用来循环两个人掷骰子的
/// </summary>
public static void Dice(bool[] isStop)
{
while (player[0] < 99 && player[1] < 99)
{
if (isStop[0] == false)
{
Begin(0);
#region a

//Console.WriteLine(playName[0] + "开始掷骰子( ̄︶ ̄)↗ (扔~)");
//rec = Console.ReadKey(true);//制造游戏后门
//if (rec.Key == ConsoleKey.U)
//{
//    ConsoleKeyInfo next = Console.ReadKey(true);
//    if (next.Key == ConsoleKey.F9)
//        i = (10,100);
//}
//else
//    i = r.Next(1, 7);//下面紧跟着显示是为了使代码更好理解,符合逻辑:掷点→看数→加数→走棋

//Console.WriteLine(playName[0] + "掷出了{0} \n\tA开始走{0}格~~", i);
//player[0] += i;
//player[0] = Judge(player[0]);//,out flag);
//if (player[0] < 99)
//{
//    if (player[0] != player[1])
//    {
//        switch (map[player[0]])
//        {
//            case 1:
//                Drawmap();
//                Console.WriteLine("{0},欢迎进入幸运抉择:", playName[0]);
//                Console.WriteLine("输入 y 则与对手交换当前位置;输入 n 则让对手后退5格");
//                Limit(ref player[0], ref player[1]);
//                Console.Clear();
//                //Drawmap();
//                break;
//            case 2:
//                Console.WriteLine("B O O M!!{0}踩中地雷,后退六格", playName[0]);
//                player[0] -= 6;
//                player[0] = Judge(player[0]);
//                //Drawmap();
//                break;
//            case 3://暂停

//                Drawmap();
//                isStop0 = true;
//                Console.WriteLine("{0}暂停一回合", playName[0]);
//                Console.ReadKey(true);
//                Console.Clear();

//                break;
//            case 4:
//                Drawmap();
//                Console.WriteLine("欢迎{0}进入时空隧道,请坐稳扶好,即将前进八格", playName[0]);
//                player[0] += 8;
//                player[0] = Judge(player[0]);
//                //Drawmap();
//                break;
//            default: //Drawmap();
//                break;
//        }
//        Drawmap();
//        Console.WriteLine("现在位置:\n{0}={2}\n{1}={3}", playName[0], playName[1], player[0], player[1]);
//    }
//    else
//    {
//        player[1] = 0;
//        Drawmap();
//        Console.WriteLine("{1}被{0}踩到,{1}受伤严重,住院休息后重新开始冒险!~~", playName[0], playName[1]);
//    }
//}
//else//这句话必须有,如果a掷到99以上,那么游戏结束
//{
//    Drawmap();//显示地图上用户已经走到头
//    Console.ForegroundColor = ConsoleColor.Black;//强调下
//    Console.BackgroundColor = ConsoleColor.White;
//    Console.WriteLine(playName[0] + "   Win!");
//    Console.ResetColor();//不还原下面的文字也会跟这个结果一致
//    break;
//}

#endregion
}
else//isStop==true
{
Console.WriteLine("{0}休息一回合", playName[0]);
isStop[0] =false;
}
if (isStop[1] == false)
{
Begin(1);
#region b

//Console.WriteLine(playName[1] + "开始掷骰子( ̄︶ ̄)↗ (扔~)");//掷点
//rec = Console.ReadKey(true);
//if (rec.Key == ConsoleKey.F12)
//{
//    n = 20;
//}
//else
//    n = r.Next(1, 7);//看数
//Console.WriteLine(playName[1] + "掷出了{0} \n\tB开始走{0}格~~", n);//看数
//player[1] += n;//加数

//player[1] = Judge(player[1]);//,out flag);//开始走棋
//if (player[1] < 99)
//{
//    if (player[0] != player[1])
//    {
//        switch (map[player[1]])
//        {
//            case 1:
//                Drawmap();
//                Console.WriteLine("{0},欢迎进入幸运抉择:", playName[1]);
//                Console.WriteLine("输入 y 则与对手交换当前位置;输入 n 则让对手后退5格");
//                Limit(ref player[1], ref player[0]);
//                Console.Clear();
//                //Drawmap();
//                break;
//            case 2:
//                Console.WriteLine("B O O M!!{0}踩中地雷,后退六格", playName[1]);
//                player[1] -= 6;
//                player[1] = Judge(player[1]);
//                //Drawmap();
//                break;
//            case 3://暂停
//                Drawmap();
//                isStop1 = true;
//                Console.WriteLine("{0}暂停一回合", playName[1]);
//                Console.WriteLine("{0}下一回合停止掷骰子", playName[1]);
//                Console.Clear();
//                break;
//            case 4:
//                Drawmap();
//                Console.WriteLine("欢迎{0}进入时空隧道,请坐稳扶好,即将前进八格", playName[1]);
//                player[1] += 8;
//                player[1] = Judge(player[1]);
//                //Drawmap();
//                break;
//            default:// Drawmap();
//                break;
//        }
//        Drawmap();
//        Console.WriteLine("现在位置:\n{0}={2}\n{1}={3}", playName[0], playName[1], player[0], player[1]);
//    }
//    else
//    {
//        player[0] = 0;
//        Drawmap();
//        Console.WriteLine("{0}被{1}踩到,{0}受伤严重,住院休息后重新开始冒险!~~", playName[0], playName[1]);
//    }
//}
//else
//{
//    Drawmap();//显示地图上用户已经走到头
//    Console.ForegroundColor = ConsoleColor.Black;//强调下
//    Console.BackgroundColor = ConsoleColor.White;
//    Console.WriteLine(playName[1] + "   Win!");
//    Console.ResetColor();//不还原下面的文字也会跟这个结果一致
//    break;
//}

#endregion
}
else
{
Console.WriteLine("{0}休息一回合", playName[1]);
isStop[1] = false;
}
}
Console.Clear();
ShowUI();
if (player[0] >= 99)
{
Drawmap();//显示地图上用户已经走到头
Console.ForegroundColor = ConsoleColor.Black;//强调下
Console.BackgroundColor = ConsoleColor.White;
Console.WriteLine(playName[0] + "   Win!");
Console.ResetColor();//不还原下面的文字也会跟这个结果一致
}
else
{
Drawmap();//显示地图上用户已经走到头
Console.ForegroundColor = ConsoleColor.Black;//强调下
Console.BackgroundColor = ConsoleColor.White;
Console.WriteLine(playName[1] + "   Win!");
Console.ResetColor();//不还原下面的文字也会跟这个结果一致
}
}

/// <summary>
/// 这个方法是用来掷骰子
/// </summary>
/// <param name="who">用来识别当前掷骰子的人</param>
public static void Begin(int who)//传参,0为A,1为B。
{
int i=0;
ConsoleKeyInfo rec;
Console.WriteLine(playName[who] + "开始掷骰子( ̄︶ ̄)↗ (扔~)");
rec = Console.ReadKey(true);//制造游戏后门
if (rec.Key == ConsoleKey.U)//if(rec.Key==ConsoleKey.Tab && rec.Modifiers==(ConsoleModifiers.Control|ConsoleModifiers.Shift))
{
ConsoleKeyInfo next = Console.ReadKey(true);
if (next.Key == ConsoleKey.F9)
i = r.Next(10, 100);
}
else
i = r.Next(1, 7);//下面紧跟着显示是为了使代码更好理解,符合逻辑:掷点→看数→加数→走棋

Console.WriteLine(playName[who] + "掷出了{0} \n\tA开始走{0}格~~", i);
player[who] += i;
player[who] = Judge(player[who]);//,out flag);
if (player[who] < 99)
{
if (player[who] != player[1-who])
{
switch (map[player[who]])
{
case 1:
Drawmap();
Console.WriteLine("{0},欢迎进入幸运抉择:", playName[who]);
Console.WriteLine("输入 y 则与对手交换当前位置;输入 n 则让对手后退5格");
Limit(ref player[who], ref player[1-who]);
Console.Clear();
//Drawmap();
break;
case 2:
Console.WriteLine("B O O M!!{0}踩中地雷,后退六格", playName[who]);
player[who]= 6;
player[who]= Judge(player[who]);
//Drawmap();
break;
case 3://暂停

Drawmap();
isStop[who] = true;
Console.WriteLine("{0}暂停一回合", playName[who]);
Console.ReadKey(true);
Console.Clear();

break;
case 4:
Drawmap();
Console.WriteLine("欢迎{0}进入时空隧道,请坐稳扶好,即将前进八格", playName[who]);
player[who] += 8;
player[who] = Judge(player[who]);
//Drawmap();
break;
default: //Drawmap();
break;
}
Drawmap();
Console.WriteLine("现在位置:\n{0}={2}\n{1}={3}", playName[0], playName[1], player[0], player[1]);
}
else
{
player[1-who] = 0;
Drawmap();
Console.WriteLine("{1}被{0}踩到,{1}受伤严重,住院休息后重新开始冒险!~~", playName[who], playName[1-who]);
}
}
}

/// <summary>
/// 这个方法是用来判断特殊位置,从而执行特殊情况
/// </summary>
/// <param name="now">now是用来获得掷出骰子与当前位置相加后的实际点数</param>
/// <returns></returns>
static public int Judge(int now)//,out bool flag)
{
//flag = false;
if ( now>= 99)
{
now = 99;
//flag = true;
//Console.ReadKey(true);两个用户都引用这个方法,没有办法显示谁胜利
//Console.Clear();如果非要在此步显示结果,只能显示“99 win!”
//Drawmap();因为a,b的绘制是由ForJudge中player[i]决定的
}
else if (now < 0)
now = 0;

Console.ReadKey(true);
Console.Clear();
return now;
}

/// <summary>
/// 这个方法是进入幸运抉择之后的走棋。调用了Drawmap
/// </summary>
/// <param name="player1">承载A的位置</param>
/// <param name="player2">承载B的位置</param>
/// <returns>返回一个变量但不接收</returns>
static public char Limit(ref int player1,ref int player2)
{
char input;
do
{
try
{
Console.Write("y/n:");
input = Convert.ToChar(Console.ReadLine());
if (input == 'y' || input == 'n')
break;
else
{
Console.WriteLine("请输入y/n");
}
}
catch
{
Console.WriteLine("请输入y/n");
}
}
while (true);
if(input=='y')
{
int temp=player1;
player1=player2;
player2=temp;
Console.WriteLine("双方开始互换位置");
Console.ReadKey(true);
}
else
{
Console.WriteLine("对方开始后退六格");
player2-=5;
player2=Judge(player2);
}
return input;
}
}
}


-------
Windows Phone 7手机开发、.Net培训、期待与您交流! -------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: