Java编写掷骰子游戏
骰子游戏源代码

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课后习题

(5)采用public、private、protected以及默认等类型的成员创建一个类,然后定义这个类的一个对象。观察在访问所有类成员时会出现哪种类型的编译错误。
(6)编写一个类,它具有public、private、protected以及默认等类型的成员,将这个类存放在某个包中。在另外一个包内再编写第二个类,在此类内编写一个方法,以操作第一个类内的各个数据成员,观察在访问所有成员时会出现哪种类型的编译错误。
(5)编写一个“猜数”游戏:程序在1~100之间随机地选择一个数,然后在一个标签中显示一个提示:“猜一个1~100之间的数”,当在文本框中输入一个数并按Enter键后,若猜大了,文本框的背景色变成红色,并在另外一个标签中显示“猜大了,重猜!”,反之,若猜小了,文本框背景色变成蓝色,并在标签中显示“猜小了,重猜!”。若猜对了,显示“猜对了,真棒!”,文本框的内容这时变成不可编辑。另外提供一个按钮,单击该按钮可以重新玩这个游戏。
【1】判断两个integerSet类对象S1和S2是否相等。提示:集合相等的前提是所有元素相等。
【2】输出两个集合对象的交集。
【3】输出两个集合对象的并集。
【4】将一个整形数据插入到一个集合对象中。
【5】从一个集合中删除某一个元素。
(5)编写一个具有两种方法的基类base,并在第一个方法内调用第二个方法。然后编写一个派生类derived,并覆盖父类中的第二个方法,产生一个derived类对象,将它向上类型转换(即转换为base类型),并调用第一个方法。验证并解释运行结果。
第8章
(4)编写一个程序,采用命令行参函数输入一个文本文件名和一个字符串,在这个文件内查找这个字符串。要求输出具有该字符串的所有文件行。
(5)编写一个程序,比较两个文本文件的内容是否相同。
实验三Java猜数字游戏开发

实验三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程序设计》课内实验指导书

北京理工大学珠海学院计算机学院《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实验)

使⽤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实现掷骰⼦控制台和窗体两种⽅法本⽂实例为⼤家分享了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)蓝桥杯 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;}// 待补充......。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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();// 通知观察者 }}。