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;}// 待补充......。
Java实验报告-扔骰子

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版)

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("猜⾼了,不要放弃哦↖(^ω^)↗。
BoBing博饼(java控制台输出)

}
else if(sum[1]==5||sum[2]==5||sum[3]==5||sum[5]==5||sum[6]==5)
{
System.out.print("\t"+arry[i].Nsijin);
System.out.print("\t"+arry[i].Nsanhong);
System.out.println("\t"+arry[i].Nduitang);
{
if(j==6)
System.out.print(dice[j]+" 四进,恭喜");
else System.out.print(dice[j]+",");
}
if(sijin1<sijin) {sijin1++; arry[t].Nsijin++;}
sanhong=sc.nextInt();
System.out.println("设置四进奖品数:");
sijin=sc.nextInt();
System.out.println("设置对堂奖品数:");
duitang=sc.nextInt();
//System.out.println("设置状元奖品数:");
// zhuangyuan=sc.nextInt();
System.out.println("设置参与人数:");
骰子模拟程序设计

骰子模拟程序设计一、设计目标模拟实现骰子游戏。
二、设计要求1. 通过按某键模拟投掷骰子。
2. 模拟显示骰子的旋转,经过一段时间后骰子静止,根据静止时的数字大小确定输赢。
3. 通过按某键可停止骰子旋转。
4. 模拟投掷骰子的力度,通过按某键的时间长短或两次按键之间的时间间隔,控制骰子的旋转时间和转速。
5. 通过按某键可正常退出模拟程序。
三、设计提示本课题可用1~8分别代替骰子的八面数字,当按下某键的时候,数字开始滚动显示,当按下结束键时停止,屏幕上显示的就是当前数字。
其中,按键检测、数字显示、时间长短均可以通过DOS、BIOS功能调用完成。
STACK SEGMENTDW 64 DUP(?)STACK ENDSDATA SEGMENTMESSAGE DB'NOTE:ENTER "1,2,3" TO CHOOSE SPEED,"S" TO STOP,"E" TO EXIT','$'RESULT DB'YOUR NUMBER IS ','$' GO DB'GOING!','$'STOP DB'STOP!','$'TIME DB?DATA ENDSCODE SEGMENTASSUME DS:DATA,CS:CODEPOINT MACRO OP1,OP2 ;置光标位置PUSH AXPUSH BXPUSH DXMOV AH,02HMOV BH,0MOV DH,OP1MOV DL,OP2INT 10HPOP DXPOP BXPOP AXENDMPRINT MACRO M ;输出字符PUSH AXPUSH DXMOV DL,MMOV AH,02HINT 21HPOP DXPOP AXENDMSTART:MOV AX,DATAMOV DS,AXLEA SI,TIMEMOV AH,01HMOV CX,3000HINT 10HMOV AX,0600HMOV BH,0CHXOR CX,CXMOV DX,1850HINT 10HPOINT 7,18LEA DX,MESSAGEMOV AH,09HINT 21HMOV AX,0600HMOV BH,0FCHMOV CX,0B26HMOV DX,0D2AHINT 10HPOINT 12,20LEA DX,RESULTMOV AH,09HINT 21HRESET:MOV AH,08INT 21HCMP AL,'1'JZ A0CMP AL,'2'JZ A0CMP AL,'3'JZ A0CMP AL,'E'JZ EXITJMP RESETA0:AND AH,00HMOV CL,0FFHMUL CLMOV CX,AXPUSH CXPOINT 9,38LEA DX,GOMOV AH,09HINT 21HPOP CXA1:PUSH CXCALL RANDPOP CXADD BL,31HPOINT 12,40PRINT BLMOV AH,01HINT 16HCMP AL,'S'JZ CONTINUELOOP A1CONTINUE:POINT 9,38LEA DX,STOPMOV AH,09HINT 21HMOV AH,01HINT 16HCMP AL,'1'JZ A1CMP AL,'2'JZ A1CMP AL,'3'JZ A1CMP AL,'E'JZ EXITJMP RESETRAND PROCPUSH CXPUSH DXPUSH AXCALL DELAYCALL DELAYMOV AH,00H INT 1AHMOV AX,DXAND AH,00HMOV DL,6DIV DLMOV BL,AHPOP AXPOP DXPOP CXRETRAND ENDPDELAY PROCPUSH CXPUSH DXMOV DX,DEC DXJNZ D11D11: MOV CX,0FFFFHD12: LOOP D12POP DXpop CXRET DELAY ENDPEXIT: INT 20HAG: JMP AGCODE ENDSEND START调试结果:按下一次“1”键后:再按下一次“1”键后:。
基于C++实现掷双骰游戏的示例代码

基于C++实现掷双骰游戏的⽰例代码在最流⾏的博彩游戏中有⼀种名为“掷双骰”(craps)的骰⼦游戏,这种游戏在世界各地的娱乐场所和⼤街⼩巷⾮常受欢迎。
游戏的规则很简单:玩家掷两个骰⼦。
每个骰⼦有六⾯,分别含有1、2、3、4、5和6个点。
掷完骰⼦后,计算两个朝上的⾯的点数之和。
1、如果⾸次投掷的点数总和是7或者11,那么玩家赢;2、如果⾸次投掷的点数只和事2、3或者12(称为"craps"),那么玩家输(即庄家赢);3、如果⾸次投掷的点数只和事4、5、6、7、8、9或者10,那么这个和就成为玩家的“⽬标点数”。
要想赢的话,玩家必须连续的掷骰⼦直到点数与这个⽬标点数相同为⽌,即“得到了点数”。
但在得到点数前,如果掷到的是7,就会输掉。
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;unsigned int rollDice();int main() {enum Status {CONTINUE, WON, LOST}; //这个就是⾃定义⼀个变量类型,就类似于int,double这种,即这⾥的说⽩了就是设置⼀个枚举类变量类//⽽这个类的关键字就是Status,以这个类型定义的变量只能取枚举内的⼏个值,⽽这⼏个值⼜对应了数字。
srand(static_cast<unsigned int>(time(0)));unsigned int myPoint = 0;Status gameStatus = CONTINUE;unsigned int sumOfDice = rollDice();switch (sumOfDice) {case 7:case 11:gameStatus = WON;break;case 2:case 3:case 12:gameStatus = LOST;break;default:gameStatus = CONTINUE;myPoint = sumOfDice;cout << "Point is " << myPoint << endl;break;};while (gameStatus == CONTINUE){sumOfDice = rollDice();if (sumOfDice == myPoint)gameStatus = WON;else if (sumOfDice == 7)gameStatus = LOST;}if (gameStatus == WON)cout << "Player wins" << endl;elsecout << "Player lose" << endl;}unsigned int rollDice(){unsigned int die1 = 1 + rand() % 6;unsigned int die2 = 1 + rand() % 6;unsigned int sum = die1 + die2;cout << "Player rolled: " << die1 << " + " << die2<< " = " << sum << endl;return sum;}这个是我拿来当作笔记的,主要是为了记住这么个问题,当我要想循环的实现博彩游戏并且统计输赢的时候,会⾃然⽽然的想到在外部套⼀个for循环去执⾏,但是这样就会涉及到⼀个问题,即随机数的⽣成,按照我最开始的理解是随着循环的进⾏,给srand提供的seed不同(也就是实参time(0))就会在每次循环都产⽣不同的随机序列。
Java语言程序设计(基础篇)原书第十一版 梁勇 第5、6章 课后题答案

System.out.println("Month\t\tCD Value");
for (int i=1;i<month+1;i++){
money=money+money*rate/1200;
System.out.println(i+"\t\t"+money);
}
mean=sum/10;
double a=num-Math.pow(sum,2)/i;
standard=Math.pow(a/(i-1),0.5);
System.out.println("平均值是:"+mean);
System.out.print("方差是:"+standard);
}
}
5.47商业:检测ISBN-13
System.out.print("请输入10个数:");
Scanner in=new Scanner(System.in);
for (i=0;i<10;i++) {
list[i] = in.nextDouble();
sum += list[i];
num += Math.pow(list[i],2);
char d7=str.charAt(6);char d8=str.charAt(7);char d9=str.charAt(8);
char d10=str.charAt(9);char d11=str.charAt(10);char d12=str.charAt(11);
范例1(掷骰子)

范例题目一制作一个投骰子游戏。
程序运行界面如图1所示。
图1 筛子游戏界面3.1.1程序功能如图1所示:游戏运行,可以显示不同点数的筛子;游戏开始,按下“回车键”,则筛子随机出现不同的点数,产生动画效果;按下“回车键”,筛子停止变化,记录点数;按下“空格键”,更换游戏者,重复上述2、3步骤;按下“q键”,游戏结束。
该游戏可以多人参加,每人可以投多次,每人每次的筛子点数自动累加,点数最高者胜。
3.1.2实现步骤1)搭建程序框架新建一个空的工程,工程名称game;将colorConsole.h(附件1)和colorConsole.cpp(附件2)拷贝到工程当前目录,添加到工程中;新建一个主文件main.cpp,将#include “colorConsole.h”代码添加到main.cpp 中。
2)代码实现(源代码见附件3)一个辅助函数void rolldice(HANDLE hOutput, int n, int col , int row, WORD wColors[]);输入参数:输出屏幕:hOutput筛子点数:n屏幕位置:列col行row文字颜色:wColors[]输出参数:无功能:在屏幕指定位置输出指定点数和指定颜色的筛子主函数功能:检测按键,根据不同的按键实现不同的功能,算法思想如下面的为代码所示。
void main(){屏幕初始化;显示6个黄色的不同点数的筛子;在屏幕底部显示菜单;while(1)//游戏开始{if (检测到按键){if(检测是否按下“回车键”){标志位取反;if(当前标志为false){停止投筛子;显示当前点数的筛子;rolldice(handle,i+1,row,col,wColors);记录并显示游戏者和点数;}}else if (检测是否按下“空格键”){计数器清零;游戏者人数加1;}else if (检测是否按下“q或Q键”)break;}if (标志位是true){随机投筛子;}}}//游戏结束3)程序编译调测运行不需要额外的设置,常规调试运行即可。
java方法练习题及答案.doc

java方法练习题及答案整理:Lemon题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少?题目:判断101-200之间有多少个素数,并输出所有素数。
程序分析:判断素数的方法:用一个数分别去除2到sqrt,如果能被整除,则表明此数不是素数,题目:打印出所有的”水仙花数”,所谓”水仙花数”是指一个三位数,其各位数字立方和等于该数本身。
例如:153是一个”水仙花数”,因为153=1的三次方+ 5的三次方+ 3的三次方。
题目:将一个正整数分解质因数。
例如:输入90,打印出90=2*3*3*5 o程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。
如果nk,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n,重复执行第一步。
题目:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
《Java基础入门》习题答案第1章Java开发入门一、填空题1、Java EE、Java SE、Java ME2、JRE3、javac4、bin5、path、classpath二、选择题1、ABCD、C、D、B、 B三、简答题1、面向对象、跨平台性、健壮性、安全性、可移植性、多线程性、动态性等。
2、JRE,它相当于操作系统部分,提供了Java程序运行时所需要的基本条件和许多Java基础类,例如,10类、GUI控件类、网络类等。
JRE是提供给普通用户使用的,如果你只想运行别人开发好的Java程序,那么,你的计算机上必须且只需安装JRE0JDK,它包含编译工具、解释工具、文档制作工具、打包工具多种与开发相关的工具,是提供给Java开发人员使用的。
Java 测试16531

Java 测试1:
一.(难度100)
投骰子比赛(随机数比较)程序:
程序要求:
1)制作一个投骰子比赛程序:计算机先投骰子(生成一个1~6之间的随机点数),再由你投骰子(生成一个1~6之间的随机点数),比较你扔出的点数和计算机扔出的点数的大小。
2)比赛采用“三局两胜制”。
3)如果你扔出的点数大于计算机扔出的点数,则显示信息:“这次你赢了!”;否则,如果你扔出的点数小于计算机扔出的点数,则显示信息“这次你输了!”;如果双方点数相同,此局无效(不计入3局总数)。
4)直到三次比赛的机会结束,显示最后比赛的结果:如果你赢了(注意:先赢两次就算取胜),显示“恭喜你,你取得了胜利!!”;如果你输了,显示“太不幸了,你输给了电脑!”;
5)信息显示完毕后,程序退出。
(程序提示:)
A)可以使用java.util包中的Random类的nextInt(int)方法,或ng包中的
Math类的random( )方法来生成随机数
B)程序退出语句为System.exit(0);
C)程序需要完整的输入或输出显示,语法要符合Java规范,代码要有合理的注释和
缩进格式。
- 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();// 通知观察者 }}。