大家都是第一次一起做完整的项目,刚发布作业的时候看到这么庞大的代码量心里没底,但是真正上手实践之后,发现我们是可以做成功的。正所谓万事开头难,把源码填完之后思路就打开了,然后就是拿好几个下午各种优化重构。想过搞图形化界面,但是看了好几天的课程,最后还是实现不了,看来我们要学的还有很多。这段日子里大家一起约研讨室合代码,跑代码,发现问题并且解决问题。群策群力,好事多磨。
package FlyChess;
public class GameDisplay {
public static void SplashScreen() {
System.out.println("**************************************************************");
System.out.println("* *");
System.out.println("* *");
System.out.println("* 飞行棋游戏 *");
System.out.println("* *");
System.out.println("* *");
System.out.println("**************************************************************\n");
}
public static void startGame() {
System.out.println("\n");
System.out.print("**************************************************************\n");
System.out.print("* Game Start *\n");
System.out.print("**************************************************************\n");
}
public static void gameOver() {
System.out.println("\n\n\n\n");
System.out.print("****************************************************\n");
System.out.print(" Game Over \n");
System.out.print("****************************************************\n\n");
}
public static void selectRole(Player player1,Player player2) {
System.out.println("玩家1" + player1.Name + "的士兵:A");
System.out.println("玩家2" + player2.Name + "的士兵:B\n");
}
public static void winner(Player player1,Player player2) {
if (player1.Pos > player2.Pos) {
System.out.println("\n恭喜" + player1.Name + "将军! 您获胜了!");
} else {
System.out.println("\n恭喜" + player2.Name + "将军! 您获胜了!");
}
}
public static void pause(Player curPlayer){
System.out.println("\n" + curPlayer.Name + "停掷一次!\n"); // 显示此次暂停信息
}
public static void result(Player curPlayer, int step) {
System.out.println("-----------------"); // 显示结果信息
System.out.println(curPlayer.Name + "刚才得到的骰子数: " + step);
}
public static void curPosition(Player player1, Player player2) {
System.out.print(player1.Name + "(A)当前位置:" + player1.Pos + " ");
System.out.println(player2.Name + "(B)当前位置:" + player2.Pos);
System.out.println("-----------------");
}
public static void printThrow(Player playerMax){
System.out.print(playerMax.Name + ", 请您按任意字母键后回车启动掷骰子: ");
}
public static void selectPolicy(int type,Player player) {
if (type== 0) {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~人 机 对 战~~~~~~~~~~~~~~~~~~~~~~~~\n");
player.type = 0;
} else {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~两 人 对 战~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
System.out.println("请选择角色: 1. 关羽 2. 张飞 3. 吕布 4. 赵云");
}
public static void reSelect() {
System.out.println("对战类型输入错误,请重新输入你要选择的角色");
}
public static void pkType() {
System.out.println("请选择对战类型:0-人机对战 1-两人对战");
}
}
package FlyChess;
import java.util.*;
public class GameEngine {
GameMap map; // 地图
int type;
Player player1=new Player();
Player player2=new Player();
/**
* 初始化游戏的一局
*/
public void init() {
map = new GameMap();
map.createMap(); // 生成地图
}
/**
* 开始游戏
*/
public void start() throws InterruptedException {
// 初始化
init();
GameDisplay.SplashScreen();
GameDisplay.pkType();
Scanner input=new Scanner(System.in);
while(true) {
if (input.hasNextInt()) {
type = input.nextInt();
if (type != 0 && type != 1)
GameDisplay.reSelect();
else break;
}
else {
GameDisplay.reSelect();
String string=input.next();//清除缓存区回车
}
}
GameDisplay.selectPolicy(type, player2);
if(type==1){
int role=player1.setName(1,0);
player2.setName(2,role);
}
else {
int beforeRole=player1.setName(1,0);
System.out.print("电脑选择角色");
int role=(int)(Math.random()*100)%4+1;
while(role==beforeRole){
role=(int)(Math.random()*100)%4+1;
}
player2.setRole(role);
}
play(); // 开始两人对战
}
/**
* 两人对战玩法
*/
public void play() throws InterruptedException {
GameDisplay.startGame();
// 显示对战双方士兵样式
GameDisplay.selectRole(player1,player2);
// 显示对战地图
map.showMap(player1.Pos, player2.Pos);
// 游戏开始
// int step; // 存储骰子数目
while (player1.Pos < 99 && player2.Pos < 99) { // 有任何一方走到终点,跳出循环
move(player1,player2);
if(player1.Pos>=99)
break;
move(player2,player1);
}
// 游戏结束
GameDisplay.gameOver();
GameDisplay.winner(player1,player2);
}
public void move(Player curPlayer, Player opponent) throws InterruptedException {
int step;
if (curPlayer.goAndStop.equals("on")) {
step = ThrowShifter.throwShifter(curPlayer); // 掷骰子
GameDisplay.result(curPlayer,step);
curPlayer.getCurPos(map, step, opponent); // 计算这一次移动后的当前位置
GameDisplay.curPosition(player1,player2);
// 显示对战地图
map.showMap(player1.Pos,player2.Pos); // 显示当前地图
}
else {
GameDisplay.pause(curPlayer); // 显示此次暂停信息
curPlayer.goAndStop = "on"; // 设置下次可掷状态
}
}
}
package FlyChess;
public class GameMap {
int[] map = new int[100]; //对战地图,注意,以下数组中的index从0开始,故第1个地雷实际出现在地图上的第5个位置
int[] luckyTurn =new int[8]; //幸运轮盘
int[] landMine =new int[8]; //地雷位置,第1个地雷实际出现在地图上的第6个位置
int[] pause =new int[6]; //暂停
int[] timeTunnel =new int[6]; //时空隧道
int[] countTable=new int[5]; //数空格惩罚
int[] connerLocate=new int[5]; //记录地图拐角坐标
int[] startEnd=new int[2];
/**
* 生成地图:
* 关卡代号为:1:幸运轮盘 2:地雷 3: 暂停 4:时空隧道 0:普通 5:卍 数空格惩罚
*/
public void createMap(){
int i;
//在对战地图上设置幸运轮盘
for(i = 0; i < luckyTurn.length; i++){
luckyTurn[i]=(int)(Math.random()*100)%98+1; //起点和终点没有
map[luckyTurn[i]] = 1;
}
//在对战地图上设置地雷
for(i = 0; i < landMine.length; i++){
int a=(int)(Math.random()*100)%98+1;
while(map[a]!=0){
a=(int)(Math.random()*100)%98+1;//不和别的关卡重复
}
landMine[i]=a;
map[landMine[i]] = 2;
}
//在对战地图上设置暂停
for(i = 0; i < pause.length; i++){
int a=(int)(Math.random()*100)%98+1;
while(map[a]!=0){
a=(int)(Math.random()*100)%98+1;
}
pause[i]=a;
map[pause[i]] = 3;
}
//在对战地图上设置时空隧道
for(i = 0; i < timeTunnel.length; i++){
int a=(int)(Math.random()*100)%98+1;
while(map[a]!=0){
a=(int)(Math.random()*100)%98+1;
}
timeTunnel[i]=a;
map[timeTunnel[i]] = 4;
}
//在对战地图上设置数空格
for(i = 0; i < countTable.length; i++){
int a=(int)(Math.random()*100)%98+1;
while(map[a]!=0){
a=(int)(Math.random()*100)%98+1;
}
countTable[i]=a;
map[countTable[i]] = 5;
}
//设置拐角坐标数组,控制随机地图的长度3
connerLocate[0]=(int)(Math.random()*100)%35+1;
connerLocate[1]=(int)(Math.random()*100)%11+connerLocate[0]+1;
connerLocate[2]=(int)(Math.random()*100)%35+connerLocate[1]+1;
connerLocate[3]=(int)(Math.random()*100)%11+connerLocate[2]+1;
/*d1=connerLocate[0] 第一行长度
*d2=connerLocate[2]-connerLocate[1] 第二行长度
* 限制第一行和第二行的显示长度为40
*connerLocate[4]记录的是第一行和第二行的显示空格的最短长度
* 目的:地图居左显示
* */
connerLocate[4]=Math.min(40-connerLocate[0],40-(connerLocate[2]-connerLocate[1]+1));
/*记录起点终点前的空格个数
*即startEnd[0]第一行起点前要显示的空格个数
*因为“起点”“终点”对应图标单占一行
*startEnd[1]也可理解为最后一行的长度
* */
startEnd[0]=40-connerLocate[0]-connerLocate[4];//减去起点,点下标为0
startEnd[1]=40-(connerLocate[2]-connerLocate[1]+1)-connerLocate[4]+100-(connerLocate[3]+1);//空格+最后剩下的没打印地图标
}
/**
* 输出地图的奇数行(第1、3行)
* @param start 输出的起始点在地图上的位置
* @param end 输出的结束点在地图上的位置
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
//a是connerLocate[4],最短显示空格数
public void showLine1(int a,int start, int end, int playerPos1, int playerPos2){
for(int j=1;j<=a;j++)
System.out.print(" ");
for(int i = start; i <=end; i++){
System.out.print(GetGraph.getGraph(map[i], i, playerPos1, playerPos2));
}
}
/**
* 输出地图的偶数行(第2行)
* @param start 输出的起始点在地图上的位置
* @param end 输出的结束点在地图上的位置
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showLine2(int a,int start, int end, int playerPos1, int playerPos2){
for(int j=1;j<=a;j++)
System.out.print(" ");
for(int i = end; i > start; i--){
System.out.print(GetGraph.getGraph(map[i], i, playerPos1, playerPos2));
}
}
/**
* 输出地图的右竖列
* @param a 要打的空格个数
* @param start 输出的起始点在地图上的位置
* @param end 输出的结束点在地图上的位置
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showRLine(int a,int start, int end, int playerPos1, int playerPos2){
for(int i = start+1; i <=end; i++){
for (int j = a; j >=0; j--) {
System.out.print(" ");
}
System.out.println(GetGraph.getGraph(map[i], i, playerPos1, playerPos2));
}
}
/**
* 输出地图的左竖列
* @param start 输出的起始点在地图上的位置
* @param end 输出的结束点在地图上的位置
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showLLine(int a,int start, int end, int playerPos1, int playerPos2){
for(int i = start+1; i < end; i++){
for(int j=1;j<=a;j++)
System.out.print(" ");
System.out.println(GetGraph.getGraph(map[i], i,playerPos1, playerPos2));
}
}
/**
* 显示对战地图
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
*/
public void showMap(int playerPos1, int playerPos2){
System.out.println("图例说明:○ 起点; ▓▓ 终点; ■ 暂停; ¤ 幸运轮盘; ★ 地雷; 〓 时空隧道; - 普通; 数字 当前位置序号\n地图如下:");
for (int j = startEnd[0]; j > 0; j--) {
System.out.print(" ");
}
System.out.println("起点→");
//显示地图第一行
showLine1(40-connerLocate[0]-connerLocate[4],0, connerLocate[0], playerPos1, playerPos2);
System.out.println(); //换行
//显示地图右竖行
showRLine(40-connerLocate[4],connerLocate[0],connerLocate[1],playerPos1,playerPos2);
//显示地图第二行
showLine2(40-connerLocate[2]+connerLocate[1]-connerLocate[4],connerLocate[1],connerLocate[2],playerPos1,playerPos2);
System.out.println(); //换行
//显示地图左竖行
showLLine(40-connerLocate[2]+connerLocate[1]-connerLocate[4],connerLocate[2],connerLocate[3],playerPos1,playerPos2);
//显示地图第3行
showLine1(40-connerLocate[2]+connerLocate[1]-connerLocate[4],connerLocate[3],99,playerPos1,playerPos2);
System.out.println();
// for (int j = startEnd[1]-2; j > 0; j--) {
for (int j = startEnd[1]+3; j > 0; j--) {
System.out.print(" ");
}
System.out.println("→终点");
}
}
package FlyChess;
public class GetGraph {
/**
* 显示地图关卡对应的图形
* @param i 地图当前位置的关卡代号,即图例符号的代号
* @param index 当前地图位置编号
* @param playerPos1 玩家1的当前位置
* @param playerPos2 玩家2的当前位置
* @return 地图当前位置的对应图片
*/
public static String getGraph(int i, int index, int playerPos1, int playerPos2){
String graph ="";//局部变量赋初值
//设置给定的地图位置index的正确的图形符号graph,graph的可能值包括:
//AB(2个玩家恰好同在位置index)
if((playerPos1==index)&&(playerPos2==index))
graph="AB";
//A(玩家1恰好在位置index)
else if(playerPos1==index)
graph="A";
//B(玩家2恰好在位置index)
else if(playerPos2==index)
graph="B";
//¤、★、■、〓、-(2个玩家均不在位置index,则按关卡代号i相应设置图形符号)
// ■ 3 暂停; ¤ 1 幸运轮盘; ★ 2 地雷; 〓 4 时空隧道; - 普通;
else if (i==1) {
graph="¤ ";
}
else if (i==2) {
graph="★";
}
else if (i==3) {
graph="■ ";
}
else if (i==4) {
graph="〓";
}
else if (i==5) {
graph="卍";
}
//○ 地图的起点
else if(index==0){
graph="○";
}
//▓▓地图的终点
else if(index==99){
graph="▓▓";
}
//5 地图位置5时显示全角的5,在其它位置(10,15...)时显示半角数字字符
else if(index==5){
graph="5";
}
else if (index%5==0) {
graph=Integer.toString(index);
}
else{
graph="-";
}
return graph;
}
}
package FlyChess;
import java.util.Scanner;
public class Player {
int type = 1;//电脑玩家标记0,真人玩家标记1
int Pos = 0;//对战中玩家的当前位置
String goAndStop = "on";// 走或停标识设置
String Name;// 对战角色
public void setRole(int role) {
switch (role) {
case 1:
Name = "关羽";
break;
case 2:
Name = "张飞";
break;
case 3:
Name = "吕布";
break;
case 4:
Name = "赵云";
break;
default:
break;
}
}
public int setName(int i, int beforeRole) {
Scanner input = new Scanner(System.in);
System.out.print("请玩家" + i + "选择角色: ");
int role;
while (true) {
if (input.hasNextInt()) {
role = input.nextInt();
if (role <= 0 || role >= 5 || beforeRole == role)
System.out.println("玩家" + i + "输入错误,请重新输入你要选择的角色");
else break;
} else {
System.out.println("玩家" + i + "输入错误,请重新输入你要选择的角色");
String string = input.next();//清除缓存区回车
}
}
setRole(role);
return role;
}
/**
* 计算玩家此次移动后的当前位置
*/
public void getCurPos(GameMap map, int step, Player opponent) {
Pos = Pos + step; // 第一次移动后的位置
if (Pos >= 99) {
Pos = 99;
return;
}
// Scanner input = new Scanner(System.in);
boolean flag=true;
while(flag&&(map.map[Pos]!=0)&&Pos>=0&&Pos<=99){
switch (map.map[Pos]) { // 根据地图中的关卡代号进行判断
case 1: // 幸运轮盘
Rules.LuckyTurn(this);
break;
case 2: // 踩到地雷
Rules.landmine(this);
break;
case 3: // 下一次暂停一次
Rules.Pause(this);
flag=false;
break;
case 4: // 时空隧道
Rules.timeTunnel(this, opponent);
flag=false;
break;
case 5: // 数空格惩罚
Rules.countSpace(this);
flag=false;
}
}
// 返回此次掷骰子后玩家的位置坐标
if (Pos < 0) {
Pos = 0;
} else if (Pos > 99) {
Pos = 99;
}
}
}
package FlyChess;
import java.util.Scanner;
public class Rules {
public static void LuckyTurn(Player curPlayer) {
System.out.println(curPlayer.Name+"走到了幸运轮盘");
int cnt = (int) (Math.random() * 100) % 3+4;//生成一个4到6的随机数决定前进步数
if (cnt == 4) {
curPlayer.Pos+= 4;
System.out.println(curPlayer.Name+"前进四步");
} else if (cnt == 5) {
curPlayer.Pos+= 5;
System.out.println(curPlayer.Name+"前进五步");
} else if (cnt == 6) {
curPlayer.Pos+= 6;
System.out.println(curPlayer.Name+"前进六步");
}
}// 幸运轮盘
public static void landmine(Player curPlayer) {
// 踩到地雷
System.out.println(curPlayer.Name+"踩到了地雷");
int cnt1 = (int) (Math.random() * 100) % 4;
if (cnt1 == 0)
System.out.println("对手送"+curPlayer.Name+"一包老坛酸菜");
else if (cnt1 == 1) {
curPlayer.Pos-= 1;
System.out.println(curPlayer.Name+"后退一步");
} else if (cnt1 == 2) {
curPlayer.Pos-= 2;
System.out.println(curPlayer.Name+"后退两步");
} else if (cnt1 == 3) {
curPlayer.Pos-= 3;
System.out.println(curPlayer.Name+"后退三步");
}
}// 踩到地雷
public static void Pause(Player curPlayer) {
System.out.println("慢慢来的都是诚意,好戏啊都在烟火里");
System.out.println(curPlayer.Name+"暂停一次");
curPlayer.goAndStop= "off";
}
public static void timeTunnel(Player curPlayer, Player opponent) {
System.out.println("希望是火,失望是烟,生活总是点燃了火,又冒着了烟");
System.out.println("时空隧道环节,选手交换位置");
int temp = curPlayer.Pos;
curPlayer.Pos= opponent.Pos;
opponent.Pos= temp;
}
public static void countSpace(Player curPlayer)
{
Scanner input = new Scanner(System.in);
if(curPlayer.type==0){
System.out.println(curPlayer.Name+"受到惩罚后退5步");
curPlayer.Pos-=5;
}
int x=(int)(Math.random()*100)%30;
System.out.println("惩罚"+curPlayer.Name+"数出括号内空格的数量");
System.out.print("[");
for(int i=1;i<=x;i++)
System.out.print(" ");
System.out.println("]");
System.out.println("请输入"+curPlayer.Name+"数出的空格个数");
int y;
if (input.hasNextInt()) {
y = input.nextInt();
if (y != x) {
System.out.println("那夜吹着风刮着大雨,一个往西一个向东,分离的滋味犹如曼珠沙华,见叶不见花见花不见叶,我想这一离别便是一辈子。\n" + curPlayer.Name + "返回起点");
curPlayer.Pos = 0;
} else {
System.out.println("数对了!");
}
}
else {
System.out.println("不,朋友,我们好像已经渐行渐远了,过去我们在一起很快乐。可现在,我们不能兼容了。我们应该分道扬镳了,这就是人生。也许将来我们会再次相逢,请你勿忘我。\n"+curPlayer.Name + "返回起点");
curPlayer.Pos = 0;
}
}
}
package FlyChess;
import javax.swing.*;
public class StartGame {
public static void main(String[] args) throws InterruptedException {
GameEngine game = new GameEngine(); //创建游戏类
game.start(); //开始游戏
}
}
package FlyChess;
import java.util.Scanner;
public class ThrowShifter {
public static int throwShifter(Player curPlayer) throws InterruptedException {
Scanner input = new Scanner(System.in);
if(curPlayer.type==0){
System.out.println("电脑正在掷骰子");
Thread.sleep(2500);
return (int)(Math.random()*100)%6+1;
}
GameDisplay.printThrow(curPlayer);
String answer = input.next();
// 产生一个1~6的数字,即掷的骰子数目
return (int)(Math.random()*100)%6+1;
}
}