
正文
拿火柴游戏java代码 拿火柴游戏java代码
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
现有21根火柴,两人轮流取,每人每次可取1到3根。不可多取,也不能不取,谁取最后一根火柴谁输 java 代码
1、按照题目的游戏规则,先拿第一根的人(先手)必输无疑。
把顺次取的每一根火柴都编上序号(1—21),因为21=(4+1)×4+1,而每次拿的火柴数是1—4根,这样,计算机作为后手就能控制游戏进程:计算机根据刚才先手拿走的数目,凑成5,拿到第5根火柴且只拿到第5根为止,就逼迫先手去拿第6根。6=5+1。以此类推,后手总是最后拿第5k根(k是自然数),先手总是被逼先拿第5k+1根,以致第21根落在自己手中而失败。
2、欲想获胜,只能修改游戏规则。例如
①、人先拿,每次1—4根,谁取最后一根谁输,但火柴总根数改作22根或27根。这时先手一旦拿到第5k+1根立刻暂停,让机器去拿那第5k+2根。
或者②、人先拿,每次1—5根,谁取最后一根谁输,火柴总根数21不变。这时,人的制胜方案是把2、8、14、20号火柴抢到手而把第3、9、15、21号火柴让给对方。
相关问答
Q1: 谁拿最后一根火柴 程序设计 大家帮帮忙!
这个道理和编程无关,每人最多取4根,
1+4=5
21=5*4+1
也就是说,只要保证每轮两方之和是5,那么4轮后取走20根,最后先取的人必定取最后一根。
第二题:需要用递推的方式,计算所有必胜必输的状态,然后保证每次取火柴都让对方到达必输状态。
所谓必输就是只剩最后一根,或者无论怎么取后的结果都是必胜。
所谓必胜,就是可以对方到达必输状态的情况。
程序如下:
import java.io.*;
public class Picker {
// 火柴堆的输赢状况
private final static int EMPTY=0; // 这种排列不可能出现,如108
private final static int UNKNOWN=1; // 尚未计算出
private final static int WIN=2; //必胜
private final static int LOSE=3; //必输(如果对方够聪明)
// 用数组,保存每种火柴堆排列的输赢状态,下标为排列,如357, 111, 001, 100等等
private int[] status;
public Picker() {
// 初始化状态数组,排除所有不可能出现的情况
status = new int[358]; // 0 - 357
int i,j,k;
for (i=0; i=3; i++) {
for (j=0; j=5; j++) {
for (k=0; k=7; k++) {
status[i*100+j*10+k] = UNKNOWN;
}
}
}
// 已知 100, 010, 001必输
status[1]=LOSE;
status[10]=LOSE;
status[100]=LOSE;
// 所有能使对方到达上述三个状态的排列都是必赢的
markWin(1);
markWin(10);
markWin(100);
// 递推计算,直至357的情况被计算出来
while (status[357] == UNKNOWN) {
//找到第一个没有计算的
int node=2;
for (node = 2; node357; node++) {
if (status[node] == UNKNOWN) break;
}
// 它的所有下个状态肯定都是必赢,不然以前就能算出。
status[node] = LOSE;
// 所有能使对方到达这个状态的排列都是必赢的
markWin(node);
}
}
// 所有能使下个状态变必输的排列都是必赢的
private void markWin(int node) {
// 假设node为必输
// 每堆的数量分别为i,j,k
int i = node / 100;
int j = node / 10 % 10;
int k = node % 10;
// 先是第一堆,可能为i+1, i+2, ..., 3
for (int i1 = i+1; i1 = 3; i1++) {
status[i1*100+j*10+k] = WIN;
}
// 第二堆
for (int j1 = j+1; j1 = 5; j1++) {
status[i*100+j1*10+k] = WIN;
}
// 第三堆
for (int k1 = k+1; k1 = 7; k1++) {
status[i*100+j*10+k1] = WIN;
}
}
// 查找所有可能的一次取火柴后的排列,找出其中必输的状态,把这个作为自己的走法
public int getWinPick(int node) {
//每堆的数量分别为i,j,k
int i = node / 100;
int j = node / 10 % 10;
int k = node % 10;
// 先是第一堆,可能留下0, 1, ..., i-1
for (int i1 = 0; i1 i; i1++) {
if (status[i1*100+j*10+k]==LOSE) return i1*100+j*10+k;
}
// 第二堆
for (int j1 = 0; j1 j; j1++) {
if (status[i*100+j1*10+k]==LOSE) return i*100+j1*10+k;
}
// 第三堆
for (int k1 = 0; k1 k; k1++) {
if (status[i*100+j*10+k1]==LOSE) return i*100+j*10+k1;
}
// 没有找到,那么先顽强抵抗一下,只取一根
if (i0) return (i-1)*100+j*10+k;
else if (j0) return (j-1)*10+k;
else return k-1;
}
public static void main(String[] args) throws Exception {
Picker picker = new Picker();
// 一开始的排列是357
int node = 357;
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
while (node 0) {
// 计算机先
System.out.print("Now is "+node);
node = picker.getWinPick(node);
System.out.println(", I pick to "+node);
if (node == 0) {
System.out.println("I lose");
return;
}
// 对方再取
System.out.println("Now is your turn: ");
String input = stdin.readLine();
int node1 = 0;
try {
node1 = Integer.parseInt(input);
} catch (Exception e) {
System.out.println("Invalid input, you lose");
break;
}
// 这里没有判断取的是否合法,即node和node1之间是否仅差一位数字
if ( node1==0 ) {
System.out.println("You lose");
}
node = node1;
}
}
}
这个程序只是例子,是说明算法,没有判断输入的合法性,所以不能一直输入2的,人嘛,自己也遵循一下游戏规则吧。
另外,稍做改动,如果不利,计算机不会马上认输了。
Q2: 求一个JAVA“拿火柴小游戏”的程序 要求如下!!!求!!!!!!!!!!!!!!!!
按照题目要求,人拿完火柴后计算机自动拿火柴,判断胜利者。鼠标点击ok或者键盘按enter键即可提交人拿的火柴个数。图形界面如下,
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Random;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
public class game extends javax.swing.JFrame implements ActionListener{
private JPanel frame;
private JTextField pwd;
private JTextField jLabel1;
private JTextField jLabel2;
private JButton bntOk;
private JLabel l1;
private JLabel l2;
private JLabel l3;
int total;
public static void main(String[] args)
{
game ff=new game();
}
public game(){
initGUI();
Random r=new Random();
total=r.nextInt(100);
jLabel2.setText(String.valueOf(total));
this.setSize(500, 500);
this.setLocation(300, 400);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getRootPane().setDefaultButton(bntOk);
bntOk.addActionListener(this);
}
public void actionPerformed(java.awt.event.ActionEvent evt)
{
int a=Integer.parseInt(jLabel1.getText());
if((a3)||(a==0)){
JOptionPane.showMessageDialog(game.this,"输入错误\n请重新输入");
return;
}
total=total-a;
jLabel2.setText(String.valueOf(total));
if(total=0){
JOptionPane.showMessageDialog(game.this,"恭喜你,胜利了!");
return;
}
Random r=new Random();
int b=r.nextInt(4);
while(b==0)
b=r.nextInt(4);
pwd.setText(String.valueOf(b));
total=total-b;
jLabel2.setText(String.valueOf(total));
if(total=0){
JOptionPane.showMessageDialog(game.this,"很遗憾,你输了!");
}
}
private void initGUI(){
frame=new JPanel();
getContentPane().add(frame, BorderLayout.CENTER);
frame.setLayout(null);
bntOk =new JButton();
bntOk.setText("OK");
bntOk.setBounds(150, 200, 66, 30);
frame.add(bntOk);
jLabel2= new JTextField();
jLabel2.setBounds(150, 50, 100, 50);
frame.add(jLabel2);
l1=new JLabel();
l1.setText("火柴数量");
l1.setBounds(90, 50, 100, 50);
frame.add(l1);
jLabel1= new JTextField();
jLabel1.setText("");
jLabel1.setBounds(200,149, 77, 22);
frame.add(jLabel1);
l2=new JLabel();
l2.setText("我拿火柴");
l2.setBounds(100, 149, 77, 22);
frame.add(l2);
l3=new JLabel();
l3.setText("对方拿火柴");
l3.setBounds(100, 249, 77, 22);
frame.add(l3);
pwd = new JTextField();
pwd.setBounds(200, 249, 77, 22);
frame.add(pwd);
bntOk.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e1) {
int a=Integer.parseInt(jLabel1.getText());
if((a3)||(a==0)){
JOptionPane.showMessageDialog(game.this,"输入错误\n请重新输入");
return;
}
total=total-a;
jLabel2.setText(String.valueOf(total));
if(total=0){
jLabel2.setText("0");
JOptionPane.showMessageDialog(game.this,"恭喜你,胜利了!");
return;
}
Random r=new Random();
int b=r.nextInt(4);
while(b==0)
b=r.nextInt(4);
pwd.setText(String.valueOf(b));
total=total-b;
jLabel2.setText(String.valueOf(total));
if(total=0){
JOptionPane.showMessageDialog(game.this,"很遗憾,你输了!");
}
}
}
);
}
}
关于拿火柴游戏java代码和拿火柴游戏java代码的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。







