Java编写掷骰子游戏
- 格式:doc
- 大小:27.00 KB
- 文档页数:8
7.1 程序的源代码★Main()文件: // 文件路径名:dice_game\main.cpp#include "utility.h" // 实用程序软件包#include "dice_game.h" // 骰子游戏int main(void) // 主函数main(void){DiceGame objGame; // 骰子游戏对象objGame.Game(); // 运行游戏system("PAUSE"); // 调用库函数system()return 0; // 返回值0, 返回操作系统}★dice_game.h文件: // 文件路径名: dice_game\dice_game.h #ifndef __DICE_GAME_H__ // 如果没有定义__DICE_GAME_H__#define __DICE_GAME_H__ // 那么定义__DICE_GAME_H__typedef enum{WIN, LOSE, TIE} GameStatus; // WIN:赢,LOSE:输,TIE:平局// 骰子游戏类DiceGame声明class DiceGame{private:// 数据成员:int numOfWin; // 胜利数次int numOfLose; // 失败数次int numOfTie; // 平局数次// 辅助函数int RollDice(); // 模拟投掷一次骰子void Help(); // 获得帮助void Show(); // 显示统计结果public:// 方法声明:DiceGame(); // 无参数的构造函数virtual ~DiceGame(){} // 析构函数void Game(); // 模拟游戏};// 骰子游戏类DiceGame的实现部分DiceGame::DiceGame() // 初始化骰子游戏{numOfWin = 0; // 胜利数次numOfLose = 0; // 失败数次numOfTie = 0; // 平局数次cout << "游戏开始" << endl;}int DiceGame::RollDice() // 模拟投掷一次骰子,返回值为所投掷的两颗骰子向上一面的点数之和{int numOfDice1; // 所投掷的第1颗骰子向上一面的点数int numOfDice2; // 所投掷的第2颗骰子向上一面的点数int sum; // 所投掷的两颗骰子向上一面的点数之和numOfDice1 = 1 + Rand::GetRand(6); // 模拟所投掷骰子1的点数numOfDice2 = 1 + Rand::GetRand(6); // 模拟所投掷骰子2的点数sum = numOfDice1 + numOfDice2; // 计算所投掷两颗骰子向上一面的点数之和cout << "选手掷骰子:" << numOfDice1 << "+" << numOfDice2 << "=" << sum << endl;return sum; // 返回所掷骰子向上一面点数之和}void DiceGame::Help() // 获得帮助{cout << " 游戏者每次投掷两颗骰子,每个骰子是一个正方体,有" << endl; cout << "6面上面分别标有1、2、3、4、5、6个圆点,当骰子停止时" << endl; cout << ",将每个骰子朝上的点的数相加,在第一次投掷骰时, 如果" << endl;cout << "所得到的和为7或11,那么游戏者为赢得胜利; 如果所得到" << endl;cout << "的和为2、3或12,那么游戏者为输掉了;如果和为4、5、6" << endl; cout << "、8、9或10,那么为游戏者的点数;如要想赢得胜利,必" << endl; cout << "须继续投掷骰子,直到取得自已的点数为止, 但是如果投" << endl;cout << "掷出的和为7或投掷6次仍未赚到该点数,则游戏者为输了." << endl << endl;}void DiceGame::Show() // 显示统计结果{cout << "选手游戏统计:" << endl;cout << "获胜" << numOfWin << "次" << endl;cout << "失败" << numOfLose << "次" << endl;cout << "平局" << numOfTie << "次" << endl;}void DiceGame::Game() // 模拟游戏int select = 1;int sum, myPoint;GameStatus status; // 游戏状态Rand::SetRandSeed(); // 设置当前时间为随机数种子Help(); // 获得帮助while(select!=3){cout << endl << endl << "请选择:" << endl;cout << "1. 获得帮助" << endl;cout << "2. 玩一手游戏" << endl;cout << "3. 退出游戏" << endl;cin >> select; // 输入选择if(select!=1&&select!=2&&select!=3) //若输入不是 1,2,3 重新输入{cout<<"请用1,2,3回答"<<endl;continue;}if(1){while(select==1) //输入1,帮助{Help();break;}if(select==2) //输入2{sum=RollDice(); //模拟掷骰子switch(sum){case 7: //掷得7或11胜利case 11:status=WIN;numOfWin++;break;case 2: //投掷得2、3、12,输了 case 3:case 12:status=LOSE;numOfLose++;break;default: //投得其他数值,处于平局 status=TIE;myPoint=sum;numOfTie++;cout<<"点数"<<myPoint<<endl;}while(1){if(status==WIN){cout<<"恭喜你,赢得游戏!"<<endl;break;}if(status==LOSE){cout<<"很遗憾,你输了!"<<endl;break;}while(status==TIE){cout<<"你现在是平局,是否要继续游戏";if(UserSaysYes()){int again;again=RollDice(); //处于平局再次掷骰子if(myPoint==again) //掷得自己的点数,赢得胜利{status=WIN;numOfWin++;break;}else if(again==7) //掷得7,输了{status=LOSE;numOfLose++;break;}else //平局{numOfTie++;if(numOfTie == 6) //平局6次,输了{status=LOSE;cout<<"你已平局6次,";break;}}}}}}else if(select==3) //输入为3{if(UserSaysYes()) //退出游戏break;elseselect=1; //返回游戏}}}Show(); // 显示统计结果}#endif★Utility.h文件:#ifndef __UTILITY_H__ // 如果没有定义__UTILITY_H__ #define __UTILITY_H__ // 那么定义__UTILITY_H__// 实用程序工具包#ifdef _MSC_VER // 表示是Visual C++#if _MSC_VER == 1200 // 表示Visual C++6.0// 标准库头文件#include <string.h> // 标准串和操作#include <iostream.h> // 标准流操作#include <limits.h> // 极限#include <math.h> // 数据函数#include <fstream.h> // 文件输入输出#include <ctype.h> // 字符处理#include <time.h> // 日期和时间函数#include <stdlib.h> // 标准库#include <stdio.h> // 标准输入输出#include <iomanip.h> // 输入输出流格式设置#include <stdarg.h> // 支持变长函数参数#include <assert.h> // 支持断言#else // 其它版本的Visual C++// ANSI C++标准库头文件#include <string> // 标准串和操作#include <iostream> // 标准流操作#include <limits> // 极限#include <cmath> // 数据函数#include <fstream> // 文件输入输出#include <cctype> // 字符处理#include <ctime> // 日期和时间函数#include <cstdlib> // 标准库#include <cstdio> // 标准输入输出#include <iomanip> // 输入输出流格式设置#include <cstdarg> // 支持变长函数参数#include <cassert> // 支持断言using namespace std; // 标准库包含在命名空间std中#endif // _MSC_VER == 1200#else // 非Visual C++// ANSI C++标准库头文件#include <string> // 标准串操作#include <iostream> // 标准流操作#include <limits> // 极限#include <cmath> // 数据函数#include <fstream> // 文件输入输出#include <cctype> // 字符处理#include <ctime> // 日期和时间函数#include <cstdlib> // 标准库#include <cstdio> // 标准输入输出#include <iomanip> // 输入输出流格式设置#include <cstdarg> // 支持变长函数参数#include <cassert> // 支持断言using namespace std; // 标准库包含在命名空间std中#endif // _MSC_VER// 实用函数char GetChar(istream &inStream = cin); // 从输入流inStream中跳过空格及制表符获取一字符bool UserSaysYes(); // 当用户肯定回答(yes)时, 返回true,用户否定回答(no)时,返回false// 函数模板template <class ElemType >void Swap(ElemType &e1, ElemType &e2); // 交换e1, e2之值template<class ElemType>void Display(ElemType elem[], int n); // 显示数组elem的各数据元素值// 实用类class Timer; // 计时器类Timerclass Error; // 通用异常类class Rand; // 随机数类Randchar GetChar(istream &in) // 从输入流in中跳过空格及制表一字符{char ch; // 临时变量while ((ch = in.peek()) != EOF // 文件结束符(peek()函数从输入流中接受1// 字符,流的当前位置不变) && ((ch = in.get()) == ' ' // 空格(get()函数从输入流中接受1字符,流// 的当前位置向后移1个位置) || ch == '\t')); // 制表符return ch; // 返回字符}bool UserSaysYes() // 当用户肯定回答(yes)时, 返回true, 用户否定回答(no)时,返回false{char ch; // 用户回答字符bool initialResponse = true; // 初始回答do{ // 循环直到用户输入恰当的回答为止if (initialResponse) cout << "(y, n)?"; // 初始回答else cout << "用y或n回答:"; // 非初始回答while ((ch = GetChar()) == '\n'); // 跳过空格,制表符及换行符获取一字符initialResponse = false; // 非初始回答} while (ch != 'y' && ch != 'Y' && ch != 'n' && ch != 'N');while (GetChar() != '\n'); // 跳过当前行后面的字符if (ch == 'y' || ch == 'Y') return true; // 肯定回答返回trueelse return false; // 否定回答返回false }template <class ElemType >void Swap(ElemType &e1, ElemType &e2) // 交换e1, e2之值{ElemType temp; // 临时变量temp = e1; e1 = e2; e2 = temp; // 循环赋值实现交换e1, e2}template<class ElemType>void Show(ElemType elem[], int n) // 显示数组elem的各数据元素值{for (int i = 0; i < n; i++){ // 显示数组elemcout << elem[i] << " "; // 显示elem[i]}cout << endl; // 换行}// 计时器类Timerclass Timer{private:// 数据成员clock_t startTime;public:// 方法声明Timer(){ startTime = clock(); } // 构造函数, 由当前时间作为开始时间构造对象double ElapsedTime() const // 返回已过的时间{clock_t endTime = clock(); // 结束时间return (double)(endTime - startTime) / (double)CLK_TCK;// 计算已过时间}void Reset(){ startTime = clock(); } // 重置开始时间};// 通用异常类Error #define MAX_ERROR_MESSAGE_LEN 100class Error{private:// 数据成员char message[MAX_ERROR_MESSAGE_LEN]; // 异常信息public:// 方法声明Error(char mes[] = "一般性异常!"){ strcpy(message, mes); }// 构造函数void Show() const{ cout << message << endl; } // 显示异常信息}; // 随机数类Randclass Rand{public:// 方法声明static void SetRandSeed(){ srand((unsigned)time(NULL)); }// 设置当前时间为随机数种子static int GetRand(int n){ return rand() % n; }// 生成0 ~ n-1之间的随机数static int GetRand(){ return rand(); } // 生成0 ~ n-1之间的随机数};#endif。
实验三Java猜数字游戏开发课程:Java实验班级:201352 姓名:程涵学号:20135210成绩:指导教师:娄佳鹏实验⽇期:15.06.03实验密级:预习程度:实验时间:仪器组次:必修/选修:选修实验序号:3实验名称: Java猜数字游戏开发(姬梦馨、程涵⼩组)⼀、实验⽬的与要求:通过编写Java的应⽤系统综合实例——猜数字游戏,总结、回顾和实践⾯向对象的编程思想以及编程⽅法,并通过编写程序来掌握Java语⾔编程技巧,将学习到的知识融会贯通,同时提⾼调试程序的能⼒,养成良好的编程习惯,并增强对程序设计整体思路的把握。
⼆、设备与环境硬件:MacBookAir软件:JDK 1.8.0; eclipse三、实验内容(1)实验需求分析:1.玩家输⼊⼀个数字,数字的范围在1-100之间,系统获取随机数。
2.对玩家输⼊的数字进⾏判断⼤⼩,如果不是系统要求的数字,系统将提⽰您,您输⼊的不是数字请重新输⼊,给出提醒以便玩家进⼀步选择。
3. 玩家猜中时系统给出所⽤时间和游戏⽔平的判断,系统给出是否继续的提⽰及判断。
4.系统根据您猜数字的次数,⾃动计数.5. 直到⽤户猜到数字为⽌,提⽰信息是否继续猜数字,如果继续将进⼊下⼀次游戏,如果退出将退出游戏系统.(2)功能模块详细设计1.随机数的获取功能描述:玩家输⼊⼀个数字,数字的范围在1-100之间,系统获取随机数。
2 输⼊输出模块功能描述:对玩家输⼊的数字进⾏判断和提⽰。
如果玩家输⼊的不是系统要求的数字,系统将提⽰您,您输⼊的不是数字请重新输⼊.。
如果玩家输⼊的数字与随机⽣成数相⽐较,⽐随机⽣成数⼩.系统提⽰您,数字太⼩请您重新输⼊。
如果玩家输⼊的数字与随机⽣成数相⽐较,⽐随机⽣成数⼤.系统提⽰您,数字太⼤请您重新输⼊。
3 判断模块功能描述:系统给出对其⽔平的判断和是否继续的提⽰;对玩家要求判断执⾏。
4 ⾃动计数模块功能描述:系统根据您猜数字的次数,⾃动计数.5 结果输出模块功能描述:直到⽤户猜到数字为⽌,提⽰信息是否继续猜数字,如果继续将进⼊下⼀次游戏,如果退出将退出游戏系统.(3)代码如下图所⽰:代码:import java.util.InputMismatchException;import java.util.Scanner;public class Main {public static void main(String[] args) {// 产⽣⼀个随机数int number = (int) (Math.random() * 100) + 1;// 加⼊countint count = 0;// 在这⾥加⼊最⼤值,和最⼩值int max = 100;int min = 1;while (true) {// 键盘录⼊数据Scanner sc = new Scanner(System.in);System.out.println("欢迎进⼊“猜数字游戏”");System.out.println("请输⼊你猜得数字:(" + min + "~" + max + ")"); try {count++;int guessNumber = sc.nextInt();// 判断if (guessNumber > number) {max = guessNumber;System.out.println("猜⼤了");}else if (guessNumber < number) {min = guessNumber;System.out.println("猜⼩了");}else {System.out.println("恭喜你,只⽤了" + count + "次就猜中了!"); // 问是否继续System.out.println("请问还要继续吗?(yes)");sc = new Scanner(System.in);String str = sc.nextLine();if ("yes".equals(str)) {// 重写赋值随机数number = (int) (Math.random() * 100) + 1;count = 0;max = 100;min = 1;}else {break;}}}catch (InputMismatchException e) {System.out.println("你输⼊的数据有误");}}}}(3).游戏运⾏结果截图四、实验结果及分析通过此次Java综合性实验,我对Java有了系统的了解。
北京理工大学珠海学院计算机学院《Java程序设计》课内实验指导书撰写:赵卓君2015年6月目录实验一:Java基本语法 (4)实验二:面向对象编程 (5)实验三:异常 (9)实验四:util包和集合框架 (11)实验五:io包和输入输出 (14)实验六:GUI+JDBC编程 (16)实验七:多线程 (20)实验一:Java 基本语法一、 实验目的:熟悉Java 程序的结构,并能完成一些基本的算法操作。
熟悉Java 程序的if-else 、switch-case 语句、循环语句以及数组的用法。
二、 实验要求:1、 编写一个Java Application 程序,循环打印如下图所示图案:【提示】可以将一个整数看成是ASCII 码,转换为对应的字符。
如:(char)65 得到ASCII 码65对应的字符“A ”2、 编写一个Java 程序,接受用户输入的一个1~12之间的整数月份,利用switch 语句输出对应月份的天数。
(提示:在DOS 命令窗口里编译运行该程序,如图所示:)int month=Integer.parseInt(args[0]); //在程序中用该行代码获得输入的月份3、 定义一个包含10个整数的数组,求该数组中的最大值、最小值、平均值与总和。
运行时,在该处输入的月份提示:在DOS命令窗口里编译运行该程序,如图所示:运行时,在该处输入10个整数//获取命令行输入的10个整数int[] ary=new int[10];for (int i = 0; i<ary.length; i++)ary[i]=Integer.parseInt(args[i]);实验二:面向对象编程一、实验目的:熟练掌握类的创建与使用,理解封装与抽象的概念,理解信息隐藏以及4种访问控制修饰符的用法,熟练掌握构造方法的用法。
二、实验要求:1.问题描述➢狗生活在陆地上(是一种陆生动物),既是哺乳类的也是肉食性的。
使⽤JavaBean实现猜数字⼩游戏(Web实验)要求:游戏随机给出⼀个1—100(包括1和100)的数字,然后让你猜是什么数字。
游戏会提⽰太⼤或太⼩,从⽽缩⼩结果范围。
实例包含⼀个JavaBean(GessNumber.java)和两个JSP页⾯:guess.jsp,getNumber.jsp。
思路:使⽤ecplise,要通过javaBean实现,那么⾸先创建javaBean,然后再创建产⽣随机数的getNumber.jsp页⾯和可以交互对错的guess.jsp页⾯。
JavaBean:简单的说,JavaBean是遵循特殊规范的Java类。
按功能分,可以分为可视Bean和不可视两类。
可视Bean是在画⾯上可以显⽰的Bean,通过属性接⼝接收数据并显⽰在画⾯。
不可视Bean即JSP中时常使⽤的Bean,在程序的内部起作⽤,如⽤于求值、存储⽤户数据等。
1package chapter;//GuessNumber.java23public class GuessNumber {4private int answer=0;//⽣成的随机数5private int guessNumber=0;//⽤户猜的数6private int guessCount=0;//猜的次数7private String result=null;//返回的结果8private boolean right=false;//判断标志9public void setAnswer(int answer) {10this.answer=answer;11 guessCount=0;12 }13public int getAnswer()//这⾥写错了,写成了getAnser,导致报错Cannot find a method to read property [answer] in a bean of type [chapter.GuessNumber]14 {15return answer;16 }17public void setGuessNumber(int guessNumber) {//javabean必要的每个封装的属性都有set和get⽅法18this.guessNumber=guessNumber;19 guessCount++;20if(guessNumber==answer)21 {22 result="恭喜你,猜对了!";23 right=true;24 }25else if(guessNumber>answer)26 {27 result="对不起,你猜⼤了!";28 right=false;2930 }31else32 {33 result="对不起,你猜⼩了!";34 right=false;35 }36 }37public int getGuessNumber() {38return guessNumber;39 }40public int getGuessCount()41 {42return guessCount;43 }44public String getResult() {45return result;46 }47public boolean isRight() {//boolean型需要isxxx()⽅法48return right;49 }50public void setRight(boolean right)51 {52this.right=right;53 }5455 }需要注意的是ecplise中的javabean需要创建在当前项⽬的src中,先新建packge,再新建class。
案例:掷骰子游戏,案例:掷骰子游戏,如果骰子的总点数则游戏赢;是7,则游戏赢;否则输。
功能模型:功能模型:系统用例图用例名称:玩掷骰子参与者:玩家静态模型:静态模型:系统类图OOAD关注从对象的角度创建领域描述。
定义领域模型需要所要处理的问题的领域知识。
通过鉴别对象的概念、属性和关联来分解问题。
识别潜在的类识别潜在的类-&-对象对象是人们要研究的任何事物及对问题域中有意义的事物的抽它们既可能是物理实体,也可能是抽象概念(规则规则、象,它们既可能是物理实体,也可能是抽象概念规则、计划和事件)。
具体地说,对象可分为如下几种类型:。
具体地说,对象可分为如下几种类型:(1) 物理实体:指有形的实物,例如,飞机、汽车、计算机、书或物理实体:指有形的实物,例如,飞机、汽车、计算机、机房等。
机房等。
(2) 人或组织的角色:例如,医生、教师、学生、工人、部门或公人或组织的角色:例如,医生、教师、学生、工人、司等。
司等。
(3) 事件:指在特定时间所发生的事,例如,飞行、演出、开会、事件:指在特定时间所发生的事,例如,飞行、演出、开会、访问或事故等。
访问或事故等。
(4) 性能说明:指厂商对产品性能的说明,如产品名字、型号、规性能说明:指厂商对产品性能的说明,如产品名字、型号、格和各种性能指标等。
格和各种性能指标等。
首先我们要确定领域内的概念类,通过对用例的名词提取,我们可以获得“玩家”、“骰子”及“骰子游戏”等概念类。
然后画出其属性和关联。
动态模型:顺序图OOAD关注软件对象在问题领域内是如何相互协作来解决问题。
交互图包括通信图和顺序图两种方式。
两个人玩的扑克牌游戏的一种玩法,两个人玩的扑克牌游戏的一种玩法,请你设计一个模拟程序,它的基本功能是:(1)发两手牌发两手牌( 拟程序,它的基本功能是:(1)发两手牌(利用随机数产生(2)确定赢考和赢脾的类型扑克牌游戏规则如下:确定赢考和赢脾的类型。
器),(2)确定赢考和赢脾的类型。
Java实现掷骰⼦控制台和窗体两种⽅法本⽂实例为⼤家分享了Java控制台和窗体实现掷骰⼦的具体代码,供⼤家参考,具体内容如下程序⽬标:同时3掷骰⼦,让骰⼦转动若⼲次后停下来的正⾯朝上的数字之和⼤于9 则为⼤,⼩于等于9则为⼩⽤于需要提前选择押⼤还是⼩,程序结束返回是否押中的结果。
1.掷骰⼦控制台实现本程序分为三层:表⽰层 :⽤类Player2 实现业务逻辑层:类DiceGame2 实现数据/技术服务层:类Dice2 实现Dice2 类实现Runnable接⼝,重新run()⽅法来设置每个骰⼦转动10次,并在停下来后获取正⾯朝上的值。
DiceGame2 类中创建三个线程来模拟同时掷3个骰⼦,并能在在骰⼦转动结束后得到总点数和每个骰⼦的点数。
其中roll()⽅法开启线程, result()计算点数Player2 类主函数创建菜单,提⽰⽤户输⼊操作。
并在控制台显⽰结果。
代码如下:public class Player2 { //表⽰层public static void main(String[] args) throws InterruptedException {Scanner sc = new Scanner(System.in);while (true) {System.out.println("**************掷骰⼦游戏***************");System.out.println("请输⼊0表⽰押⼩,输⼊1表⽰押⼤,输⼊2表⽰退出");int i = sc.nextInt();if(i == 2)System.exit(0);DiceGame2 d = new DiceGame2();d.roll();Thread.sleep(500);// 主线程等待int n = d.result();if (i == 0 && n <= 9)System.out.println("恭喜你,押⼩赢了");else if (i == 0 && n > 9)System.out.println("很遗憾,押⼩输了");else if (i == 1 && n > 9)System.out.println("恭喜你,押⼤赢了");else if (i == 1 && n <= 9)System.out.println("很遗憾,押⼤输了");System.out.println();}}}class DiceGame2 { //业务逻辑层Dice2 d1, d2, d3;public DiceGame2() {}public void roll() { // 同时三个掷骰⼦d1 = new Dice2();d2 = new Dice2();d3 = new Dice2();Thread t1 = new Thread(d1);Thread t2 = new Thread(d2);Thread t3 = new Thread(d3);t1.start();t2.start();t3.start();}public int result() { // 计算点数int sum = 0;int i = d1.getUpNum();int j = d2.getUpNum();int k = d3.getUpNum();sum = i + j + k;System.out.println("掷得点数和为:" + sum + " [" + i + " - " + j + " - " + k + " ]");return sum;}//}class Dice2 implements Runnable { // 骰⼦类数据/技术服务层private int upnum;public Dice2() {this.upnum = 1;}@Overridepublic void run() {int count = 10;// 设置每颗骰⼦转动10次while (count > 0) {upnum = new Random().nextInt(6) + 1;System.out.println(Thread.currentThread().getName() + " " + upnum);count--;try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}public int getUpNum() {return upnum;}}2.掷骰⼦窗体实现窗体程序思路和控制台⼀样,只是把显⽰界⾯由控制台改为窗体。
蓝桥杯2015年第六届垒骰⼦(JAVA)蓝桥杯 2015年 第六届 垒骰⼦(JAVA)⽅法⼀:简单的dfs思路,只能得30%的分。
需要注意的是:除第⼀层外底层筛⼦都有四个⾯可选,所以diceNum==n时ans要+4,并且第⼀层也有四个⾯可选,所以最后要乘以4实际最多算到n==12左右, 再往后就极慢了package provincial_2015B;import java.util.Scanner;public class Nine {private static int[] dice;private static int[][] exclusion;private static int n;private static int ans = 0;static {dice = new int[6+1];dice[1] = 4;dice[2] = 5;dice[3] = 6;dice[4] = 2;dice[5] = 2;dice[6] = 3;exclusion = new int[6+1][6+1];}private static void dfs(int up, int diceNum) {if(diceNum == n) {ans += 4;return ;}for(int nextUp = 1; nextUp < 7; nextUp++) {if(exclusion[nextUp][dice[up]]==1)continue;dfs(nextUp, diceNum+1);}}public static void main(String[] args) {Scanner scan = new Scanner(System.in);n = scan.nextInt();int m = scan.nextInt();for(int i = 0; i < m; i++) {int a = scan.nextInt();int b = scan.nextInt();exclusion[a][b] = 1;exclusion[b][a] = 1;}for(int i = 1; i < 7; i++) {dfs(i, 1);}System.out.println(ans*4);}}⽅法⼆: 动态规划之记忆型递归⽐第⼀种快的多, 可以在之前那个算法算12的时间下算到70, 但还是达不到60%的数据package provincial_2015B;import java.util.Arrays;import java.util.Scanner;public class Nine {private static int[] dice;private static int[][] exclusion;private static int n;// private static int ans = 0;private static int[][] visited;static {dice = new int[6+1];dice[1] = 4;dice[2] = 5;dice[3] = 6;dice[4] = 2;dice[5] = 2;dice[6] = 3;exclusion = new int[6+1][6+1];}// private static void dfs(int up, int diceNum) { // if(diceNum == n) {// ans += 4;// return ;// }//// for(int nextUp = 1; nextUp < 7; nextUp++) { // if(exclusion[nextUp][dice[up]]==1)// continue;// dfs(nextUp, diceNum+1);// }// }private static int dp(int up, int diceNum) {if(diceNum == n) {return 4;}if(visited[up][diceNum]!=0)return visited[up][diceNum];int ans = 0;for(int nextUp = 1; nextUp < 7; nextUp++) { if(exclusion[nextUp][dice[up]]==1)continue;ans += dp(nextUp, diceNum+1);}visited[up][diceNum] = ans;return ans;}public static void main(String[] args) {Scanner scan = new Scanner(System.in); n = scan.nextInt();int m = scan.nextInt();for(int i = 0; i < m; i++) {int a = scan.nextInt();int b = scan.nextInt();exclusion[a][b] = 1;exclusion[b][a] = 1;}visited = new int[6+1][n+1];int ans = 0;for(int i = 1; i < 7; i++) {ans += 4*dp(i, 1);}System.out.println(ans);}}⽅法三: 标准动态规划⽐之前得都快很多, 能跑出来80%package provincial_2015B;import java.util.Scanner;public class Nine_case2 {private static int[] dice;private static int[][] conflict;private static int MOD = 1000000007;static {dice = new int[6+1];dice[1] = 4;dice[2] = 5;dice[3] = 6;dice[4] = 2;dice[5] = 2;dice[6] = 3;conflict = new int[6+1][6+1];}public static void main(String[] args) {Scanner scan = new Scanner(System.in);int n = scan.nextInt();int m = scan.nextInt();for(int i = 0; i < m; i++) {int a=scan.nextInt();int b=scan.nextInt();conflict[a][b]=1;conflict[b][a]=1;}int[][] dp = new int[n+1][6+1];for(int i = 0; i < 6+1; i++)dp[0][i]=1;for(int i = 1; i < n; i++) {for(int j = 1; j < 7; j++) {for(int k = 1; k < 7; k++) {if(conflict[dice[j]][k]==1)continue;dp[i][j]=(dp[i][j]+dp[i-1][k])%MOD;}}}long ans=0;for(int i = 1; i < 7; i++)ans=(ans+dp[n-1][i])%MOD;System.out.println(ans*4*4);}}终极⽅法: 矩阵快速幂顺便科普快速幂运算public static long quickPower(int a, int b, int mod) { // a^b % MOD// 任何数对1取模得0if(mod==1) return 0;long ans = 1;while(b!=0) {if((b&1)==1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}// 待补充......。
Java掷骰子实验报告一.设计任务与设计目标描述1.创建一个用于模拟掷骰子游戏的应用程序。
2.游戏者滚动3个骰子,每个骰子有6个面,分别代表1,2,3,4,5,6六个点。
3.当骰子停下后,计算这3个骰子上表面的点数和。
如果掷出的点数和大于或等于11,则为大;如果点数和为小于等于10,则为小。
4.玩游戏时需要先押大小,押中则胜利,否则失败。
程序模块分析:1.界面设计2.图形显示3.产生三个随机数4.输赢的条件判断5.使用表格记录输赢二.主要对象/数据结构界面设计设计思想要求界面上可以显示三个骰子,有开始按钮,下注按钮,有一表格记录输赢数据。
要求布局合理,美观,便于游戏者使用。
具体代码如下:public class MainFrame extends JFrame {private JLabel lab1;private JLabel lab2;private JLabel lab3;private JLabel labwin;private JComboBox box;private JTextField field;public static void main(String[] args) {MainFrame main=new MainFrame();main.ShowUI();}public MainFrame() {// 构造函数lab1 = new JLabel();lab2 = new JLabel();lab3 = new JLabel();field=new JTextField(10);field.setEditable(false);labwin=new JLabel("胜率");}三.主要算法1.产生随机数的算法产生随机数主要使用java.util.Random类,如下面所示,ran= new Random() 实例化一个Random对象来分别产生三个随机数。
java实现猜数字⼩游戏(Swing版)2008年的时候,在学习Java how to program第五版的时候,写过⼀个猜数字⼩游戏,是⽤Applet写的;现在,我要⽤Swing重写这个⼩游戏,同时,加⼊⼀些新功能,如:背景颜⾊(红⾊表⽰偏⾼,蓝⾊表⽰偏低)、弹框、字体控制、布局管理器的使⽤。
运⾏截屏:代码如下://Guess a number between 1 and 1000//Java how to program, 10/e, Exercise 12.14//by pandenghuang@/* (Guess-the-Number Game) Write an application that plays “guess the number” as follows:Your application chooses the number to be guessed by selecting an integer at random in the range1–1000. The application then displays the following in a label:I have a number between 1 and 1000. Can you guess my number?Please enter your first guess.A JTextField should be used to input the guess. As each guess is input, the background colorshould change to either red or blue. Red indicates that the user is getting “warmer,” and blue,“colder.” A JLabel should display either "Too High" or "Too Low" to help the user zero in. Whenthe user gets the correct answer, "Correct!" should be displayed, and the JTextField used forinput should be changed to be uneditable. A JButton should be provided to allow the user to playthe game again. When the JButton is clicked, a new random number should be generated and theinput JTextField changed to be editable.*/import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.awt.BorderLayout;import static java.awt.BorderLayout.*;public class NumberGuessGame2016 extends JFrame {int number,random,counter=0;JLabel welcomeJLabel;JLabel hintJLabel;JTextField guessField;JPanel panel;//显⽰不同背景⾊public NumberGuessGame2016() {super("猜数字⼩游戏游戏");setLayout(new BorderLayout());panel=new JPanel();panel.setBackground(Color.WHITE);welcomeJLabel= new JLabel("游戏规则:已随机⽣成⼀个1到1000的整数,您能在10次以内猜出来吗?"); welcomeJLabel.setFont(new Font("Simsun",1,10));add(welcomeJLabel,NORTH);guessField=new JTextField(20);guessField.setFont(new Font("Arial",1,10));panel.add(guessField);add(panel); //默认添加到中间hintJLabel= new JLabel("");add(hintJLabel,SOUTH);hintJLabel.setFont(new Font("Simsun",1,10));TextFieldHandler handler=new TextFieldHandler();guessField.addActionListener(handler);random=(int)(1+1000*Math.random());}private class TextFieldHandler implements ActionListener{// process textfield events@Overridepublic void actionPerformed (ActionEvent event){while(true){number=Integer.parseInt(guessField.getText());while(number!=random){number=Integer.parseInt(guessField.getText());if(number>random){hintJLabel.setText("猜⾼了,不要放弃哦↖(^ω^)↗。
Java编写掷骰子游戏这篇文章主要介绍了Java编写掷骰子游戏,需要的朋友可以参考下废话不多说了,直接奔主题。
**多线程&&观察者模式题目要求:《掷骰子》窗体小游戏,在该游戏中,玩家初始拥有1000的金钱,每次输入押大还是押小,以及下注金额,随机3个骰子的点数,如果3个骰子的总点数小于等于9,则开小,否则开大,然后判断玩家是否押对,如果未押对则扣除下注金额,如果押对则奖励和玩家下注金额相同的金钱。
分析:这个题目要求灵活运用多线程的相关知识,达到点击开始按钮时,有3个线程启动,分别控制3颗骰子的转动,在3颗骰子全部转完以后,回到主线程计算游戏结果。
//个线程控制颗骰子Thread t = new Thread();Thread t = newThread();Thread t = newThread();//启动个线程t.start();t.start();t.start();//将个线程加入主线程t.join();t.join();t.join();But,,,写完代码以后发现,这样做虽然能够保证游戏能够正确运行,但是当我点击开始按钮时,由于3个骰子线程都是直接开在主线程上的,点击开始按钮时,按钮出现下沉情况,子线程一直在后台运行,我窗体中的图片根本不会发生改变,而是直接显示最后的结果,意思就是骰子一直在后台转动,不在前台的窗体中及时更新显示。
后来在网上苦苦找寻,大神们说如果想要通过点击JButton使窗体中的JLabel/JTextFeild等其他组件及时更新,直接在JButton的监听事件的实现方法里面直接创建匿名线程,也就是说直接在actionPerformed()方法中修改代码即可,这样能保证你的组件中内容的及时变换,实现非常炫酷的效果。
代码如下:public void actionPerformed(ActionEvent e) { new Thread(new Runnable() { @Override publicvoid run() { //将外部线程类转移到窗体内部 } }).start();}But,,,But,,, 虽然非常炫酷了,能够实现图片的及时更新了,游戏结果却错了,每次我的骰子还在转动呢,我的游戏结果却早早的就出来了。
原因:3根骰子线程属于子线程,窗体线程属于主线程,问题就在于:子线程可以通过变成精灵线程来保持与主线程的同生死,但是主线程却无法控制子线程何时死亡,只有等待子线程执行完所属的run()方法,结束线程后才知道。
解决方法:在主线程(main)中开3个子线程(t1,t2,t3),在每个子线程上再开一个子子线程(t11,t21,t31)。
t1,t2,t3只运行一次,负责创建子子线程;t11,t21,t31每个线程运行多次,负责控制窗体中的图标及时更新。
这样主线程就不受子线程的影响,开始按钮也不回出现下沉的情况。
但是同样在此处使用join方法也是hold不住子线程的,毕竟t1,t2,t3只运行了一次,join对他们来说根本不起作用,想要掌控t11,t21,t31,最容易理解的办法,就是使用观察者模式了。
将窗体看做观察者,子线程看做被观察者。
子线程运行完时,通知观察者我已经运行完成,当观察者观察到子线程全都运行完时,才开始运行后续步骤。
全部代码:1.窗体package com.sxt.dice;import java.awt.Color;public class DiceFrame extends JFrame implements ActionListener, Observer { /** * 《掷骰子》控制台小游戏,在该游戏中,玩家初始拥有的金钱,每次输入押大还是押小, * 以及下注金额,随机个骰子的点数,如果个骰子的总点数小于等于,则开小,否则开大, * 然后判断玩家是否押对,如果未押对则扣除下注金额,如果押对则奖励和玩家下注金额相同的金钱。
* * 运用观察者模式个子线程分别控制个骰子,都已经结束时,通知观察者窗体,窗体观察到所有子线程都结束时,计算游戏结果 **/ private static final long serialVersionUID = L; private JTextField txtPut; private JButton btnStart; private JLabel labResult; private JComboBox<String> comboBox; private JLabel labBigOrSmall; private JLabel labPut; private JLabel labSumMoney; private JLabel labDice; private JLabel labDice; private JLabel labDice; private JLabel labSum; private JLabel labMes; private static List<Icon> imgs = new ArrayList<Icon>(); public static void main(String[] args) { new DiceFrame(); } public DiceFrame() { this.setLocationRelativeTo(null); this.setBounds(, , , );this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); getContentPane().setLayout(null); this.setResizable(false); labDice =new JLabel(""); labDice.setIcon(new ImageIcon("img/dices.jpg")); labDice.setBounds(, , , ); getContentPane().add(labDice); labSum = new JLabel("\u\uF\uD\uD\uFFA"); labSum.setBounds(, , , );getContentPane().add(labSum); labDice = new JLabel("");labDice.setIcon(new ImageIcon("img/dices.jpg"));labDice.setBounds(, , , ); getContentPane().add(labDice); labDice = new JLabel(""); labDice.setIcon(new ImageIcon("img/dices.jpg"));labDice.setBounds(, , , ); getContentPane().add(labDice); labSumMoney = new JLabel(""); labSumMoney.setForeground(Color.red);labSumMoney.setBounds(, , , );getContentPane().add(labSumMoney); labPut = newJLabel("\uC\uB\uEB\uCE\uFFA"); labPut.setToolTipText(".");labPut.setBounds(, , , ); getContentPane().add(labPut); txtPut = new JTextField(); txtPut.setBounds(, , , ); getContentPane().add(txtPut); txtPut.setColumns(); labBigOrSmall = new JLabel("\uBC\uFFA");labBigOrSmall.setBounds(, , , ); getContentPane().add(labBigOrSmall); comboBox = new JComboBox<String>(); comboBox.setBounds(, , , ); getContentPane().add(comboBox); comboBox.addItem("大");comboBox.addItem("小"); labResult = new JLabel("");labResult.setBounds(, , , ); getContentPane().add(labResult);btnStart = new JButton("START");btnStart.setBounds(, , , ); getContentPane().add(btnStart); labMes = new JLabel("<html><font size= color=red>*</font></html>");labMes.setBounds(, , , ); getContentPane().add(labMes);this.setVisible(true); imgs.add(new ImageIcon("img/.png")); imgs.add(new ImageIcon("img/.png")); imgs.add(new ImageIcon("img/.png"));imgs.add(new ImageIcon("img/.png")); imgs.add(new ImageIcon("img/.png")); imgs.add(new ImageIcon("img/.png")); btnStart.addActionListener(this); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == btnStart) { // 清除上次游戏的结果labResult.setText(""); // 获取当前下注金额,用户余额,用户押大还是押小String txt =getText().trim(); String remain =labSumMoney.getText().trim(); // 余额不足,不能开始游戏,提示用户充值 if (Integer.parseInt(remain) <= ) { JOptionPane.showMessageDialog(null, "当前余额不足,请充值~"); return; } //下注金额合法性检查 if (txt.length() == ) { // 提示用户输入labMes.setText("*请输入下注金额"); labMes.setForeground(Color.RED); return; } // 检查用户下注金额是否在有效范围内 if (Integer.parseInt(txt) <= ||Integer.parseInt(txt) > Integer.parseInt(remain)) { txtPut.setText(""); labMes.setText("下注金额应在~" +remain + "之间"); return; } // 游戏开始后相关项不可更改txtPut.setEnabled(false); labMes.setText("");comboBox.setEnabled(false); //在主线程上开t,t,t 个子线程 Thread t = new Thread() { @Override public void run() { //每个子线程上再开子子线程,控制图标变换 IconThread t = new IconThread(labDice,imgs); //给t添加观察者,即当前窗体 t.addObserver(DiceFrame.this); newThread(t).start(); } }; Thread t = new Thread() { @Override public void run() { IconThread t = new IconThread(labDice, imgs);t.addObserver(DiceFrame.this); new Thread(t).start(); } }; Thread t = new Thread() { @Override public void run() { IconThread t = new IconThread(labDice, imgs); t.addObserver(DiceFrame.this); newThread(t).start(); } }; t.start(); t.start(); t.start(); } } /** * 获取骰子点数和* * @param lab * @return sum */ private int result(JLabel lab) { // 获取当前骰子图片Icon icon = lab.getIcon(); int sum = ; for (int i = ; i <imgs.size(); i++) { if (icon.equals(imgs.get(i))) { sum += (i + ); break; } } return sum; } // 构建所有被观察者的集合 Vector<Observable> allObservables = newVector<Observable>(); @Override public void update(Observable o, Object arg) { System.out.println(o + "................."); // 如果集合中不包含当前被观察者,将此被观察者加入集合 if(allObservables.contains(o) == false){ allObservables.add(o); } // 如果集合中被观察者个数为,说明个骰子线程已经全部结束 if (allObservables.size() == ) { // 获取当前下注金额,用户余额,用户押大还是押小String txt = txtPut.getText().trim(); String remain = labSumMoney.getText().trim(); String bigOrSmall =comboBox.getSelectedItem().toString(); // 获取每个骰子点数 int sum = result(labDice); int sum = result(labDice); int sum =result(labDice); System.out.println(sum + "-" + sum + "-" + sum); int sum = sum + sum + sum; System.out.println(sum); if (sum > && "大".equals(bigOrSmall) || sum <= && "小".equals(bigOrSmall)) { // 奖励玩家相应金额 remain =String.valueOf(Integer.parseInt(remain) + Integer.parseInt(txt)); labSumMoney.setText(remain); // 显示游戏结果 labResult.setText("WIN");labResult.setForeground(Color.GREEN); labResult.setFont(new Font("宋体",Font.BOLD, )); } else { // 扣除玩家相应金额 remain =String.valueOf(Integer.parseInt(remain) - Integer.parseInt(txt));labSumMoney.setText(remain); labResult.setText("FAIL");labResult.setForeground(Color.red); labResult.setFont(new Font("宋体", Font.BOLD, )); }txtPut.setEnabled(true); comboBox.setEnabled(true); // 本次游戏结束后移除集合中所有线程 allObservables.removeAll(allObservables); } }}2.线程package com.sxt.dice;import java.util.List;importjava.util.Observable;import java.util.Random;importjavax.swing.Icon;import javax.swing.JLabel;public class IconThread extends Observable implements Runnable { /** * 运用观察者模式,将子线程作为被观察对象,一旦子线程运行完,发生改变,通知观察者 */ JLabel lab; Random random = new Random();List<Icon> imgs; public IconThread(JLabel lab, List<Icon> imgs){ b = lab; this.imgs = imgs; } @Override public void run() { //设置每颗骰子转动次 int count = ; while (count > ){ //获取一个随机数[~) int index = random.nextInt(); //从imgs集合中取相应图片放入lab中 lab.setIcon(imgs.get(index)); count--; try { Thread.sleep(); } catch (InterruptedException e) { // TODO Auto-generated catch blocke.printStackTrace(); } } this.setChanged();// 子线程运行完,发生改变this.notifyObservers();// 通知观察者 }}。