千里冰封
JAVA 浓香四溢
posts - 151,comments - 2801,trackbacks - 0
下面我们再来看看ClientControl类,这个类代码量是最多的,这个类负责整体的游戏流程和游戏逻辑,由于写这个游戏的时候并没有很好的思考,所以代码可能会比较乱:(,希望大家不要介意

/*
 * ClientControl.java
 *
 * Created on 2007年10月2日, 下午2:02
 * 此类是客户端中的关键类,此类专门负责整个程序的
 * 流程和表现,负责对外通讯
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 
*/

package com.hadeslee.apple.client;

/**
 *
 * 
@author lbf
 
*/
import com.hadeslee.apple.common.Bet;
import com.hadeslee.apple.common.INFO;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.JFrame;
import static com.hadeslee.apple.common.Constants.*;

public class ClientControl extends Thread implements KeyListener {

    
private ClientView cv; //表示视图的类
    private ClientModel cm; //表示模型的类
    private ExecutorService es; //表示一个线程池的对象
    private AudioClip[] betAu; //表示下注时的一个音频对象
    private AudioClip onceMore;
    
private AudioClip xiu;
    
private AudioClip loop;
    
private AudioClip runA;
    
private AudioClip runB;
    
private AudioClip win;
    
private AudioClip lose;
    
private Bet bet; //缓存的上一局的下注记录
    private PP p = PP.p1;
    
private volatile boolean canBet = true;
    
private volatile boolean isRunning;
    
private volatile boolean isBetting;
    
private volatile boolean isBetted;
    
private volatile boolean canMove = true//表示此时是否可以下注,是否正在附加赌
    private Image[] pkA;
    
private Image[] pkB; //表示两个人物的图像数组
    private int result; //表示PK的结果,定义在Constants类里面
    private Control con; //处理控制的类
    private int allBet = 1;
    
private int allWin = 1//表示此人所有下注,所有赢的数,此数用于控制,不能赋0,除法会异常
    private AudioClip temp; //中间变量,用于放歌用的
    private volatile boolean go;
    
private volatile boolean showMoney;
    
private volatile boolean blinkRatio; //用以控制闪动线程的
    private volatile boolean isFullScreen; //指示此时是否是全屏
    private JFrame jf; //表示此游戏的窗口

    
/** Creates a new instance of ClientControl */
    
public ClientControl() {
    }

    
public ClientControl(int id, int allMoney) {
        cm 
= new ClientModel();
        cv 
= new ClientView(cm);
        cm.setId(id);
        cm.setAllMoney(allMoney);
        cm.setInfo(
new INFO());
        
try {
            cm.getInfo().setBigBonus(
10000);
            cm.getInfo().setSmallBonus(
1000);
            cm.getInfo().setTip(
"欢迎使用单机版!!谢谢!");
        } 
catch (Exception exe) {
            exe.printStackTrace();
        }
        initModel();
        initWindow();
        initOther();
        doShowAllMoney();
    }

    
//初始化其它东西,比如声音片断
    private void initOther() {
        con 
= new Control();
        betAu 
= new AudioClip[10];
        
for (int i = 1; i < 10; i++) {
            betAu[i] 
= Applet.newAudioClip(this.getClass().getResource("sound/bet/bet" + i + ".au"));
        }
        
//初始化所有要使用的声音片段
        loop = Applet.newAudioClip(this.getClass().getResource("sound/loop.au"));
        runA 
= Applet.newAudioClip(this.getClass().getResource("sound/runA.au"));
        runB 
= Applet.newAudioClip(this.getClass().getResource("sound/runB.au"));
        onceMore 
= Applet.newAudioClip(this.getClass().getResource("sound/wu.au"));
        xiu 
= Applet.newAudioClip(this.getClass().getResource("sound/oncemore.au"));
        win 
= Applet.newAudioClip(this.getClass().getResource("sound/win/win.au"));
        lose 
= Applet.newAudioClip(this.getClass().getResource("sound/win/lose.au"));
        bet 
= new Bet();
    }

    
//初始化全屏
    private void initWindow() {
        jf 
= new JFrame("苹果机");
        jf.getContentPane().add(cv, BorderLayout.CENTER);
        jf.setSize(
800600);
        jf.setUndecorated(
true);

        jf.setVisible(
true);
        jf.setAlwaysOnTop(
true);
        jf.setLocationRelativeTo(
null);//一条简便的语句,设置窗口居中显示
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.addKeyListener(
this);
    }

    
//初始化模型
    private void initModel() {
        initImage();
        initModelOther();
    }

    
//初始化图像
    private void initImage() {
        MediaTracker mt 
= new MediaTracker(cv);
        
int index = 0;
        Image[] number 
= new Image[10];
        Image[] winNumber 
= new Image[10];
        
for (int i = 0; i < 10; i++) {
            number[i] 
= Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("pic/game/number1/" + i + ".png"));
            winNumber[i] 
= Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("pic/game/number2/" + i + ".png"));
            mt.addImage(number[i], index
++);
            mt.addImage(winNumber[i], index
++);
        }
        Image bg 
= Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("pic/game/bg.jpg"));
        Image table 
= Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("pic/game/table.png"));
        Image pkBg 
= Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("pic/game/pk.jpg"));
        mt.addImage(bg, index
++);
        mt.addImage(table, index
++);
        mt.addImage(pkBg, index
++);
        pkA 
= new Image[3];
        pkB 
= new Image[3];
        
for (int i = 0; i < 3; i++) {
            pkA[i] 
= Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("pic/game/pk/A" + i + ".png"));
            pkB[i] 
= Toolkit.getDefaultToolkit().createImage(this.getClass().getResource("pic/game/pk/B" + i + ".png"));
            mt.addImage(pkA[i], index
++);
            mt.addImage(pkB[i], index
++);
        }
        
try {
            mt.waitForAll();
        } 
catch (Exception exe) {
            exe.printStackTrace();
        }
        cm.setBg(bg);
        cm.setNumber(number);
        cm.setWinNumber(winNumber);
        
//cm.setRunA(PP.p1.other);
        cm.setTable(table);
        cm.setPkA(pkA[
0]);
        cm.setPkB(pkB[
0]);
        cm.setPKBG(pkBg);
    }

    
//初始化模型其它部份
    private void initModelOther() {
        Bet bet 
= new Bet();
        cm.setBet(bet);
        cm.addP(PP.p1);
        
//初始化线程池
        es = Executors.newCachedThreadPool();
    }

    
//专门起一个线程用于更新余额的方法
    private void doShowAllMoney() {
        es.execute(
new Runnable() {

            
public void run() {
                showMoney 
= true;
                
while (showMoney) {
                    
try {
                        Thread.sleep(
80);
                        cv.repaint(
106617310765);
                    } 
catch (Exception exe) {
                        exe.printStackTrace();
                    }
                }
            }
        });
    }

    
//专门处理下注的方法
    private synchronized void doBet(int i) {
        
if (!isBetted) {
            isBetted 
= true;
            canMove 
= false;
            cm.getBet().clearWin();
            
//doShowAllMoney();
        }
        cm.setAllMoney(cm.getAllMoney() 
- 1);
        
int bet = cm.getBet().getBet(i);
        cm.getBet().setBet(i, bet 
+ 1);
        betAu[i].play();
    }

    
//专门用来设置赔率的方法
    private void setRatio() {
        
int rad = (int) (Math.random()*100+ 1;
        
if (rad > 95) {
            cm.setRatioA(
40);
        } 
else if (rad > 85) {
            cm.setRatioA(
30);
        } 
else {
            cm.setRatioA(
20);
        }
        rad 
= (int) (Math.random()*100+ 1;
        
if (rad > 95) {
            cm.setRatioB(
20);
        } 
else if (rad > 85) {
            cm.setRatioB(
15);
        } 
else {
            cm.setRatioB(
10);
        }
    }

    
//专门处理开始跑的方法
    private void doRun() {
        
try {
            
//此时先把赔率设置好
            setRatio();
            isRunning 
= true;
            canBet 
= false;
            canMove 
= false;
            showMoney 
= false;
            INFO inf 
= cm.getInfo();
            inf.setBigBonus(cm.getBet().getTotal() 
/ 50 + inf.getBigBonus());
            inf.setSmallBonus(cm.getBet().getTotal() 
/ 100 + inf.getSmallBonus());
            cv.repaint();
            es.execute(
new Runnable() {

                
public void run() {
                    runRun();
                }
            });
        } 
catch (Exception exe) {
            exe.printStackTrace();
        }
    }

    
public void keyPressed(KeyEvent ke) {
        
int allMoney = cm.getAllMoney();
        
int code = ke.getKeyCode();
        
//先看看是不是CTRL+F,如果是的话,就表示全屏或者退出全屏了
        if (KeyEvent.VK_F == code && (ke.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) == KeyEvent.CTRL_DOWN_MASK) {
            
if (isFullScreen) {
                GraphicsDevice gd 
= GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
                
try {
                    gd.setFullScreenWindow(
null);
                    isFullScreen
=false;
                } 
catch (Exception exe) {
                    exe.printStackTrace();
                }
            } 
else {
                
//得到图形设备,也就是显示器
                GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
                
try {
                    gd.setFullScreenWindow(jf);
                    gd.setDisplayMode(
new DisplayMode(8006001660));
                    isFullScreen
=true;
                } 
catch (Exception exe) {
                    exe.printStackTrace();
                }
            }
            
return;
        }
        
//如果可以下注并且余额大于0才处理键盘事件
        if (allMoney > 0 && canBet) {
            
if (KeyEvent.VK_1 == code) {
                doBet(
1);
                cv.repaint(
245666431);
            } 
else if (KeyEvent.VK_2 == code) {
                doBet(
2);
                cv.repaint(
1295666431);
            } 
else if (KeyEvent.VK_3 == code) {
                doBet(
3);
                cv.repaint(
1975666431);
            } 
else if (KeyEvent.VK_4 == code) {
                doBet(
4);
                cv.repaint(
2645666431);
            } 
else if (KeyEvent.VK_5 == code) {
                doBet(
5);
                cv.repaint(
3695666431);
            } 
else if (KeyEvent.VK_6 == code) {
                doBet(
6);
                cv.repaint(
4745666431);
            } 
else if (KeyEvent.VK_7 == code) {
                doBet(
7);
                cv.repaint(
5425666431);
            } 
else if (KeyEvent.VK_8 == code) {
                doBet(
8);
                cv.repaint(
6105666431);
            } 
else if (KeyEvent.VK_9 == code) {
                doBet(
9);
                cv.repaint(
7125666431);
            }
        }
        
if (KeyEvent.VK_LEFT == code && canMove) {
            
if (cm.getAllMoney() > 0) {
                
if (temp != null) {
                    temp.stop();
                }
                go 
= false;
                canBet 
= false;
                cm.setAllMoney(cm.getAllMoney() 
- 1);
                cm.setWinMoney(cm.getWinMoney() 
+ 1);
                cv.repaint(
307510765);
            }
        } 
else if (KeyEvent.VK_RIGHT == code && canMove) {
            
if (cm.getWinMoney() > 0) {
                
if (temp != null) {
                    temp.stop();
                }
                go 
= false;
                cm.setAllMoney(cm.getAllMoney() 
+ 1);
                cm.setWinMoney(cm.getWinMoney() 
- 1);
                cv.repaint(
307510765);
                
if (cm.getWinMoney() == 0) {
                    canBet 
= true;
                    cm.setBet(
new Bet());
                    cm.setBetting(
false);
                    isBetting 
= false;
                    cv.repaint(
030800600);
                }
            }
        }
    }

    
public void keyTyped(KeyEvent ke) {
    }

    
public void keyReleased(KeyEvent ke) {
        
int code = ke.getKeyCode();
        
if (KeyEvent.VK_ESCAPE == code) {
            System.exit(
0);
        }
        
//如果是回车键则分为几种可能,只分两种可能,有分和没分,有分就下分,没分就跑
        if (KeyEvent.VK_ENTER == code) {
            
if (isRunning) {
                ke.consume();
            } 
else {
                doEnter();
            }
        } 
else if (KeyEvent.VK_NUMPAD1 == code || KeyEvent.VK_Q == code) {
            
if (cm.getWinMoney() > 0 && isBetting) {
                isBetting 
= false;
                result 
= A_WIN;
            }
        } 
else if (KeyEvent.VK_NUMPAD3 == code || KeyEvent.VK_P == code) {
            
if (cm.getWinMoney() > 0 && isBetting) {
                isBetting 
= false;
                result 
= B_WIN;
            }
        }
        
//要按键能出来PK界面,必须赢的钱要大于0,否则赌的没意义
        if (KeyEvent.VK_B == code) {
            
if (cm.isBetting()) {
                
//如果此时在PK,则无条件不显示
                cm.setBetting(false);
                isBetting 
= false;
                cv.repaint(
030800600);
            } 
else if (cm.getWinMoney() > 0 && canMove) {
                
//设置为可以PK
                if (temp != null) {
                    temp.stop();
                }
                go 
= false;
                cm.setBetting(
true);
                doPK();
                cv.repaint(
030800600);
            }
        }
    }

    
//定义一个同步方法以防止两个线程共同起动跑
    private synchronized void doEnter() {
        
//当前的可用分为0时,按回车就跑
        result = 0;
        cm.setBetting(
false);
        isBetting 
= false;
        go 
= false;
        
if (temp != null) {
            temp.stop();
        }
        
if (cm.getWinMoney() == 0) {
            cm.clearP();
            resetPP(); 
//无论怎么样,都要在开始把PP的记录重置
            
//如果已下注了,那就取下注的为准
            if (canBet) {

                
if (isBetted) {
                    bet 
= cm.getBet();
                    doRun();
                    isBetted 
= false;
                } 
else {
                    
if (cm.getAllMoney() >= bet.getTotal() && bet.getTotal() > 0) {
                        bet.clearWin();
                        cm.setBet(bet);
                        cm.setAllMoney(cm.getAllMoney() 
- bet.getTotal());
                        doRun();
                    }
                }
                cv.repaint(
030800600);
            }
        } 
else {
            allWin 
+= cm.getWinMoney();
            allBet 
+= cm.getBet().getTotal();
            cm.setAllMoney(cm.getAllMoney() 
+ cm.getWinMoney());
            cm.setWinMoney(
0);
            cm.setBet(
new Bet());
            canBet 
= true;
            cv.repaint(
030800600);
        }
    }

    
//起PK线程,并且设置相当的布尔量
    
//使之可以PK
    private void doPK() {
        isBetting 
= true//此时才可以将这个设为真,因为不会再跑了,所以可以押大小了
        
//doShowAllMoney();
        cm.setBetting(true);
        es.execute(
new Runnable() {

            
public void run() {
                pkRun();
            }
        });
    }

    
//处理PK的线程体
    private void pkRun() {
        
int indexA = 0;
        
int indexB = 0;
        
while (isBetting) {
            
try {
                Thread.sleep(
80);
                
int rand = (int) (Math.random()*100);
                
if (rand % 2 == 0) {
                    
if (indexA < pkA.length - 1) {
                        cm.setPkA(pkA[
++indexA]);
                    } 
else {
                        indexA 
= 0;
                        cm.setPkA(pkA[
0]);
                    }
                } 
else {
                    
if (indexB < pkB.length - 1) {
                        cm.setPkB(pkB[
++indexB]);
                    } 
else {
                        indexB 
= 0;
                        cm.setPkB(pkB[
0]);
                    }
                }
                cv.repaint(
269274254132);
            } 
catch (Exception exe) {
                exe.printStackTrace();
            }
        }
        
if (Math.random() * 10 > 1) {
            
while (indexA == indexB) {
                indexA 
= (int) (Math.random()*3);
            }
        }
        cm.setPkA(pkA[indexA]);
        cm.setPkB(pkB[indexB]);
        cv.repaint(
238258330152);
        handleResult(indexA, indexB);
    }

    
//处理结果的一个方法,针对传进来的A和B的下标,判断谁赢谁输
    private void handleResult(int a, int b) {
        
int current = 0;
        
//当A为布时
        if (a == 0) {
            
if (b == 0) {
                current 
= AB_TIE;
            } 
else if (b == 1) {
                current 
= A_WIN;
            } 
else if (b == 2) {
                current 
= B_WIN;
            }
        } 
else if (a == 1) {
            
if (b == 0) {
                current 
= B_WIN;
            } 
else if (b == 1) {
                current 
= AB_TIE;
            } 
else if (b == 2) {
                current 
= A_WIN;
            }
        } 
else if (a == 2) {
            
if (b == 0) {
                current 
= A_WIN;
            } 
else if (b == 1) {
                current 
= B_WIN;
            } 
else if (b == 2) {
                current 
= AB_TIE;
            }
        }
        
//当两者相等,则说明猜中了
        if (result == current || current == AB_TIE) {
            win.play();
            cm.setWinMoney(cm.getWinMoney() 
* 2);
            cv.repaint(
307510765);
            
try {
                Thread.sleep(
1000);
                isBetting 
= true;
                result 
= 0;
                pkRun();
            } 
catch (Exception exe) {
                exe.printStackTrace();
            }
        } 
else if (result == 0) { //如果此时等于0,则说明没有猜拳
            
//showMoney=false;
        } else {
            canBet 
= true;
            lose.play();
            cm.setWinMoney(
0);
            
//showMoney=false;
            try {
                Thread.sleep(
1000);
                cm.setBetting(
false);
                isBetting 
= false;
                cm.setBet(
new Bet());
                cv.repaint(
030800600);
            } 
catch (Exception exe) {
                exe.printStackTrace();
            }
        }
        result 
= 0;
    }

    
//计算当前的路径出发总共跑SUM步得到的结果
    private PP fromIndex(PP from, int sum, boolean isRun) {
        
if (isRun) {
            
int all = sum;
            PP[] ps 
= PP.values();
            
int index = (all + p.ordinal()) % 26;
            
return ps[index];
        } 
else {
            
int all = 5 + 7 + sum;
            PP[] ps 
= PP.values();
            
int index = (all + p.ordinal()) % 26;
            
return ps[index];
        }
    }

    
private PP fromIndex(PP from, int sum) {
        
int all = 5 + 7 + sum;
        PP[] ps 
= PP.values();
        
int index = (all + p.ordinal()) % 26;
        
return ps[index];
    }

    
//跑大四喜的实现
    private void doDaSiXi() {
        es.execute(
new Runnable() {

            
public void run() {
                runDaSiXi();
            }
        });
    }

    
//跑大四喜的方法体实现
    private void runDaSiXi() {
    }

    
//随机跑的时间用到的线程执行体
    private void runRun() {
        doBlinkRatio();
        RatioA ra 
= RatioA.A_20;
        RatioB rb 
= RatioB.B_10;
        
int total = con.getSteps(AUTO_CONTROL);
        
int sum = 0//表示已经跑的数
        
//PP p=PP.p1;//初始开始跑的位置
        cm.setRunning(true); //把模型设为正在跑的模式
        cm.setP(p);
        
//p.setImage(yellow);
        int sleepTime = 100;
        
try {
            
//先跑五个点做为起步
            runA.play();
            
for (int i = 1; i < 6; i++) {
                Thread.sleep(
200);
                p 
= p.next();
                ra 
= ra.next();
                rb 
= rb.next();
                cm.setRa(ra);
                cm.setRb(rb);
                cm.setP(p);
                
//p.setImage(yellow);
                
//cv.repaint(178,50,465,413);
                cv.repaint(p.x - 100, p.y - 100230230);
            }
            loop.loop();
            
while (sum++ < total) {
                Thread.sleep(
20);
                p 
= p.next();
                cm.setP(p);
                ra 
= ra.next();
                rb 
= rb.next();
                cm.setRa(ra);
                cm.setRb(rb);
                
//p.setImage(yellow);
                
//cv.repaint(178,50,465,413);
                cv.repaint(p.x - 100, p.y - 100230230);
            }
            loop.stop();
            runB.play();
            
//后面七个点为停步
            for (int i = 0; i < 7; i++) {
                p 
= p.next();
                cm.setP(p);
                
//p.setImage(yellow);
                Thread.sleep(sleepTime);
                sleepTime 
+= 10;
                ra 
= ra.next();
                rb 
= rb.next();
                cm.setRa(ra);
                cm.setRb(rb);
                
//cv.repaint(178,50,465,413);
                cv.repaint(p.x - 100, p.y - 100230230);
            }

            PP pps 
= p;
            
//doBlinkRun(pps);
            doRunOver(p);
        } 
catch (Exception exe) {
            exe.printStackTrace();
        }
    }

    
//根据赔率得到当前的位置
    private RatioA getRa(int ratio) {
        RatioA[] ras 
= RatioA.values();
        
for (RatioA rs : ras) {
            
if (rs.ratio == ratio) {
                
return rs;
            }
        }
        
return null;
    }

    
private RatioB getRb(int ratio) {
        RatioB[] rbs 
= RatioB.values();
        
for (RatioB rs : rbs) {
            
if (rs.ratio == ratio) {
                
return rs;
            }
        }
        
return null;
    }

    
//处理根据国数得到当前的统一陪率
    private int getRatio(int country) {
        
if (COUNTRY_A == country) {
            
return cm.getRatioA();
        } 
else if (COUNTRY_B == country) {
            
return cm.getRatioB();
        } 
else {
            
throw new RuntimeException("出了个不该出的错误!");
        }
    }

    
//确实是否亮赔率的灯
    private void doCheckBlinkRatio() {
        
if (cm.isAWin()) {
            cm.setRa(getRa(cm.getRatioA()));
        } 
else {
            cm.setRa(
null);
        }
        
if (cm.isBWin()) {
            cm.setRb(getRb(cm.getRatioB()));
        } 
else {
            cm.setRb(
null);
        }
        cv.repaint(
030800600);
    }

    
//处理跑完的场景,根据中得不同的下标,比如,跑火车,中彩金等
    private void doRunOver(PP p) throws Exception {
        doShowAllMoney();
        
//如果下标大于0,则表示中了正规的注
        if (p.getIndex() > 0) {
            canMove 
= true;
            doBlinkRun(p);
            doCheckBlinkRatio();
            cm.getBet().setWin(p.getIndex(), 
true);
            
int winMoney = 0;
            
if (p.country > 0) {
                winMoney 
= bet.getBet(p.getIndex()) * p.country;
            } 
else {
                winMoney 
= bet.getBet(p.getIndex()) * getRatio(p.country);
            }
            cm.setWinMoney(winMoney);
            cv.repaint(
307510765);
            isRunning 
= false;
            p.audio.play();
            Thread.sleep(
800);
            
if (cm.getWinMoney() > 0) {
                playMusic();
                
//doPK();
            } else {
                
if (!isRunning) {
                    cm.setBet(
new Bet());
                    canBet 
= true;
                }
            }
            cv.repaint(
030800600);
        } 
else {
            
//如果下标等于ONCE_MORE,则表示开火车
            if (p.getIndex() == ONCE_MORE) {
                doOnceMore();
            } 
else if (p.getIndex() == SONG_DENG) {
                cm.setRa(getRa(cm.getRatioA()));
                cm.setRb(getRb(cm.getRatioB()));
                p.audio.play();
                Thread.sleep(
1000);
                onceMore.play();
                Thread.sleep(
1500);
                doSongDeng(p);
            } 
else if (p.getIndex() == SMALL_BONUS) {
                p.audio.play();
                Thread.sleep(
1000);
                cm.getInfo().setSmallBonus(
0);
                cv.repaint();
            } 
else if (p.getIndex() == BIG_BONUS) {
                p.audio.play();
                Thread.sleep(
1000);
                cm.getInfo().setBigBonus(
0);
                cv.repaint();
            }
            
//下面的语句是为了调试程序而用的
            
//isBetting=true;
        }
    }

    
//专门用来播声音的方法
    private void playMusic() {
        
int NO = (int) (Math.random()*10+ 1;
        
if (isBetting) {
        } 
else {
            
if (temp != null) {
                temp.stop();
            }
            temp 
= Applet.newAudioClip(this.getClass().getResource("sound/music/music" + NO + ".au"));
            temp.loop();
        }
    }

    
//专起一个线程用于更新赔率的闪灯
    private void doBlinkRatio() {
        es.execute(
new Runnable() {

            
public void run() {
                blinkRatio 
= true;
                
while (!canMove) {
                    
try {
                        Thread.sleep(
40);
                        cv.repaint(
14149651832);
                        
if (!blinkRatio) {
                            
break;
                        }
                    } 
catch (Exception exe) {
                        exe.printStackTrace();
                    }
                }
            }
        });
    }

    
//专门用以跑开火车的方法
    private void doOnceMore() throws Exception {
        
//doBlinkRatio();
        
// blinkRatio=false;
        p.audio.play();
        PP startP 
= p;
        RatioA ra 
= RatioA.A_20;
        RatioB rb 
= RatioB.B_10;
        
int total = (int) (Math.random()*3+ 3//随机产生火车的节数
        final AudioClip wu = Applet.newAudioClip(this.getClass().getResource("sound/oncemore/wu.au"));
        
final AudioClip run = Applet.newAudioClip(this.getClass().getResource("sound/oncemore/run.au"));
        
final AudioClip stop = Applet.newAudioClip(this.getClass().getResource("sound/oncemore/stop.au"));
        
//先处理一个一个的出来
        for (int i = 0; i < total; i++) {
            Thread.sleep(
1000);
            stop.play();
            cm.addP(startP 
= startP.next());
            cv.repaint(
17850465413);
        }
        es.execute(
new Runnable() {

            
public void run() {
                
try {
                    wu.play();
                    Thread.sleep(
3500);
                    run.loop();
                } 
catch (Exception exe) {
                    exe.printStackTrace();
                }
            }
        });
        
int steps = (int) (Math.random()*26+ 60;
        
int stepAll = steps;
        
//在此控制火车的头尾,也就是说不能中到50-100倍的那个灯
        PP pto = fromIndex(p, steps + total, true);
        PP pwe 
= fromIndex(p, steps, true);
        
//当总长度大于15时,必须会一头一尾的溢出
        if (total > 15) {
            
while (!(pto.ordinal() < 15 && pwe.ordinal() > 17)) {
                steps
++;
                pto 
= fromIndex(p, steps + total, true);
                pwe 
= fromIndex(p, steps, true);
            }
        } 
else {
            
while (!(pto.ordinal() < 15 || pwe.ordinal() > 17)) {
                steps
++;
                pto 
= fromIndex(p, steps + total, true);
                pwe 
= fromIndex(p, steps, true);
            }
        }
        
while (steps > 0) {
            
//p.setImage(yellow);
            Thread.sleep(200);
            Vector
<PP> v = cm.getP();
            cm.clearP();
            ra 
= ra.next();
            rb 
= rb.next();
            cm.setRa(ra);
            cm.setRb(rb);
            
if (stepAll / 2 == steps) {
                wu.play();
            }
            
for (int i = 0; i < v.size(); i++) {
                cm.addP(v.get(i).next());
            }
            steps
--;
            cv.repaint(
17850465413);
        }
        blinkRatio 
= false;
        cm.setRa(getRa(cm.getRatioA()));
        cm.setRb(getRb(cm.getRatioB()));
        cv.repaint(
14149651832);
        run.stop();
        
//先只留一个车头,然后一个一个地出来
        Vector<PP> v = cm.getP();
        cm.clearP();
        
for (int i = v.size() - 1; i >= 0; i--) {
            PP p 
= v.get(i);
            
if (p.index > 0) {
                cm.getBet().setWin(p.index, 
true);
                stop.play();
                
int winMoney = 0;
                
if (p.country > 0) {
                    winMoney 
= bet.getBet(p.getIndex()) * p.country;
                } 
else {
                    winMoney 
= bet.getBet(p.getIndex()) * getRatio(p.country);
                }
                cm.setWinMoney(winMoney 
+ cm.getWinMoney());
            }
            cm.addP(p);
            
//doBlinkRun(p);
            
//doCheckBlinkRatio();
            cv.repaint(030800600);
            Thread.sleep(
1000);
        }
        
for (PP pp : v) {
            doBlinkRun(pp);
        }
        p 
= v.get(v.size() - 1);
        canMove 
= true;

        
if (cm.getWinMoney() > 0) {
            playMusic();
            
//doPK();
        } else {
            cm.setBet(
new Bet());
            canBet 
= true;
            cv.repaint(
030800600);
        }
        isRunning 
= false;
    }

    
//专门用以跑送灯的方法
    private void doSongDeng(PP ps) {
        p 
= ps;
        blinkRatio 
= false;
        
//即使中到火车也不一定跑,跑的概率有70%
        if (Math.random() * 100 > 30) {
            
int total = (int) (Math.random()*3+ 2;
            
while (total > 0) {
                
try {
                    
int steps = (int) (Math.random()*20+ 20;
                    xiu.play();
                    
for (int i = 0; i < steps; i++) {
                        Thread.sleep(
20);
                        p 
= p.next();
                        cm.setP(p);
                        cv.repaint(p.x 
- 100, p.y - 100230230);
                    }
                    
//如果是已经中过的,或者大奖,或者彩金等等,皆不中
                    while (p.isWin() || p.index < 0 || p.index == 5) {
                        steps
++;
                        Thread.sleep(
20);
                        p 
= p.next();
                        cm.setP(p);
                        cv.repaint(p.x 
- 100, p.y - 100230230);
                    }
                    
final PP pps = p;
                    
//doBlinkRun(pps);
                    cm.addP(p);
                    p.setWin(
true);
                    
if (p.index > 0) {
                        cm.getBet().setWin(p.index, 
true);
                        p.audio.play();
                        
int winMoney = 0;
                        
if (p.country > 0) {
                            winMoney 
= bet.getBet(p.getIndex()) * p.country;
                        } 
else {
                            winMoney 
= bet.getBet(p.getIndex()) * getRatio(p.country);
                        }
                        cm.setWinMoney(winMoney 
+ cm.getWinMoney());
                        cv.repaint(
030800600);
                    }
                    total
--;
                    Thread.sleep(
1500);
                } 
catch (Exception exe) {
                    exe.printStackTrace();
                }
            }
            
for (PP pp : cm.getP()) {
                doBlinkRun(pp);
            }
            
//doCheckBlinkRatio();
            if (cm.getWinMoney() > 0) {
                playMusic();
                
//doPK();
            } else {
                cm.setBet(
new Bet());
                canBet 
= true;
                cv.repaint(
030800600);
            }
        } 
else {
            cm.setBet(
new Bet());
            canBet 
= true;
            cv.repaint(
030800600);
        }
        canMove 
= true;
        isRunning 
= false;
    }

    
//把PP里面的元素全部还原
    private void resetPP() {
        PP[] ps 
= PP.values();
        
for (PP p : ps) {
            p.setWin(
false);
            p.setImage(p.other);
        }
    }

    
//闪动的线程方法实现
    private void doBlinkRun(final PP p) {
        es.execute(
new Runnable() {

            
public void run() {
                blinkRun(p);
            }
        });
    }

    
//终点闪动的线程体
    private void blinkRun(PP p) {
        
int total = 0;
        go 
= true;
        
while (go) {
            
try {
                Thread.sleep(
300);
                total
++;
                p.setImage(total 
% 2 == 0 ? null : p.other);
                cv.repaint(p.x, p.y, 
6060);
            } 
catch (Exception exe) {
                exe.printStackTrace();
            }
        }
        p.setImage(p.other);
        cv.repaint(
030800600);
    }

//专门定义一个类来,把一些控制的机制封装在里面
    private class Control {

        
public Control() {
        }

        
//通过传入参数的值得到该返回多少步
        
//此方法是对外的统一接口
        public int getSteps(int style) {
            
if (COMMON == style) {
                
return getCommon();
            } 
else if (WIN_MIN == style) {
                
return getWinMin();
            } 
else if (WIN_MAX == style) {
                
return getWinMax();
            } 
else if (OPEN_MAX == style) {
                
return getOpenMax();
            } 
else if (OPEN_MIN == style) {
                
return getOpenMin();
            } 
else if (OPEN_BIG_BONUS == style) {
                
return getOpenBigBonus();
            } 
else if (OPEN_SMALL_BONUS == style) {
                
return getOpenSmallBonus();
            } 
else if (OPEN_SONG_DENG == style) {
                
return getOpenSongDeng();
            } 
else if (OPEN_ONCE_MORE == style) {
                
return getOpenOnceMore();
            } 
else if (AUTO_CONTROL == style) {
                
return getAutoControl();
            } 
else if (OPEN_LOSE == style) {
                
return getOpenLose();
            } 
else {
                
return (int) (Math.random()*26+ 10;
            }
        }

        
//内部方法,实现普通跑的步数
        private int getCommon() {
            
int total = (int) (Math.random()*26+ 50;

            
//如果此时随机跑中得是大奖,则不一定给
            if (fromIndex(p, total).index == 5) {
                
if (Math.random() * 100 > 1) {
                    total 
+= 3;
                }
            }
            
//如果此时中了大小彩金,则也不一定给
            if (fromIndex(p, total).index == BIG_BONUS || fromIndex(p, total).index == SMALL_BONUS) {
                
//if(Math.random()*10000>1){
                total++;
                
//  }
            }
            
return total;
        }

        
//实现取赢最小的方案
        private int getWinMin() {
            Bet bet 
= cm.getBet();
            
int index = 0;
            
int win = Integer.MAX_VALUE;
            
int[] wins = new int[10];
            
for (int i = 1; i < 10; i++) {
                PP p 
= PP.p1;
                
while (p.index != i) {
                    p 
= p.next();
                }
                
if (p.country > 0) {
                    wins[i] 
= bet.getBet(p.getIndex()) * p.country;
                } 
else {
                    wins[i] 
= bet.getBet(p.getIndex()) * getRatio(p.country);
                }
                
if (wins[i] <= win) {
                    
if (wins[i] == win) {
                        
if (Math.random() * 10 > 5) {
                            win 
= wins[i];
                            index 
= i;
                        }
                    } 
else {
                        win 
= wins[i];
                        index 
= i;
                    }
                }
            }
            
return getTotal(p, index);
        }

        
//实现赢得最多方案
        private int getWinMax() {
            Bet bet 
= cm.getBet();
            
int index = 0;
            
int win = Integer.MIN_VALUE;
            
int[] wins = new int[10];
            
for (int i = 1; i < 10; i++) {
                PP p 
= PP.p1;
                
while (p.index != i) {
                    p 
= p.next();
                }
                
if (p.country > 0) {
                    wins[i] 
= bet.getBet(p.getIndex()) * p.country;
                } 
else {
                    wins[i] 
= bet.getBet(p.getIndex()) * getRatio(p.country);
                }
                
if (wins[i] > win) {
                    win 
= wins[i];
                    index 
= i;
                }
            }
            
return getTotal(p, index);
        }

        
//实现开最大的那个方案(50或100倍)
        private int getOpenMax() {
            
return getTotal(p, 5);
        }

        
//实现开最小的那个方案(2或5倍)
        private int getOpenMin() {
            
int rad = (int) (Math.random()*10);
            
if (rad > 5) {
                
return getTotal(p, 1);
            } 
else {
                
return getTotal(p, 9);
            }
        }

        
//实现只要让玩家输即可,不一定让玩得输最多
        public int getOpenLose() {
            
int betAll = cm.getBet().getTotal();
            
//用一个哈希表来存储输的下标和输的金额
            EnumMap<PP, Integer> lose = new EnumMap<PP, Integer>(PP.class);
            
for (int i = 1; i < 10; i++) {
                
int wins = 0;
                PP p 
= PP.p1;
                
while (p.index != i) {
                    p 
= p.next();
                }
                
if (p.country > 0) {
                    wins 
= bet.getBet(p.getIndex()) * p.country;
                } 
else {
                    wins 
= bet.getBet(p.getIndex()) * getRatio(p.country);
                }
                
if (wins < betAll) {
                    
//如果赢的小于下注的,则输的个数加1
                    lose.put(p, betAll - wins);
                }
            }
            PP last 
= PP.p1; //最后要得到的位置
            Set<PP> keys = lose.keySet();
            System.out.println(
"会输的PP的个数是:" + keys.size());
            
//分三种方式去取想要的位置
            int MyRad = (int) (Math.random()*100+ 1;
            
if (MyRad > 85) {
                
//第一种方式用权重去取到底开什么
                System.out.println("用权重去取开什么牌了");
                
double value = 0;
                Iterator
<PP> it = keys.iterator();
                
while (it.hasNext()) {
                    PP now 
= it.next();
                    
double myValue = lose.get(now) * 1.0 / now.random;
                    
if (myValue >= value) {
                        value 
= myValue;
                        last 
= now;
                    }
                }
            } 
else if (MyRad > 30) {
                
//第二种是概率去取到底开什么
                System.out.println("用概率去取什么牌了");
                
int rand = (int) (Math.random()*100+ 1//产生一个1-100的随机数
                System.out.println("产生的随机数是:" + rand);
                
//然后把要开的位置按概率从小到大排,尽量满足概率小的开
                PP[] ps = keys.toArray(new PP[keys.size()]);
                
for (int i = 0; i < keys.size(); i++) {
                    
for (int j = i + 1; j < keys.size(); j++) {
                        
if (ps[i].random > ps[j].random) {
                            PP temp 
= ps[i];
                            ps[i] 
= ps[j];
                            ps[j] 
= temp;
                        }
                    }
                }
                System.out.println(
"排列前的顺序是:" + keys);
                System.out.println(
"排列后的顺序是:");
                
for (PP now : ps) {
                    System.out.print(now 
+ ",");
                }
                System.out.println();
                
//双重循环,已经把概率小的排在前面了
                boolean isFind = false//一个布尔量,看有没有当前随机数匹配的
                for (PP now : ps) {
                    
if (now.random > rand) {
                        System.out.println(
"匹配到的是:" + now + "它的概率是:" + now.random * 2);
                        last 
= now;
                        isFind 
= true;
                        
break;
                    }
                }
                
if (!isFind) {
                    System.out.println(
"没有匹配到,随机找一个");
                    
int index = (int) (Math.random()*keys.size());
                    last 
= ps[index];
                }
            } 
else {
                
//第三种是直接以概率来取
                System.out.println("直接取概率");
                PP[] ps 
= keys.toArray(new PP[keys.size()]);
                
int index = (int) (Math.random()*keys.size());
                last 
= ps[index];
            }
            System.out.println(
"===============================================");
            
return getTotal(p, last.index);
        }

        
//表示开大彩金的实现
        private int getOpenBigBonus() {
            
return getTotal(p, BIG_BONUS);
        }

        
//表示开小彩金的实现
        private int getOpenSmallBonus() {
            
return getTotal(p, SMALL_BONUS);
        }

        
//表示开出送灯的实现
        private int getOpenSongDeng() {
            
return getTotal(p, SONG_DENG);
        }

        
//表示开出跑火车的实现
        private int getOpenOnceMore() {
            
return getTotal(p, ONCE_MORE);
        }

        
//实现到传入的位置,应该全速跑的数量total
        private int getTotal(PP from, int index) {
            
int sum = (int) (Math.random()+26+ 30;
            
while (fromIndex(from, sum).index != index) {

                sum
++;
            }
            
return sum;
        }

        
//实现智能自动控
        private int getAutoControl() {
            System.out.println(
"总下注是:" + allBet);
            System.out.println(
"总赢  是:" + allWin);
            
int rad = (int) (Math.random()*100);
            System.out.println(
"随机数是:" + rad);
            
//输了九成了,这个时候送个大的
            if (allBet / allWin > 10) {
                System.out.println(
"输了九成了");
                
if (rad > 95) {
                    
return getSteps(WIN_MAX);
                } 
else if (rad > 90) {
                    
return getSteps(OPEN_SONG_DENG);
                } 
else if (rad > 80) {
                    
return getSteps(OPEN_ONCE_MORE);
                } 
else if (rad > 30) {
                    
return getSteps(COMMON);
                } 
else {
                    
return getSteps(OPEN_LOSE);
                }
            } 
else if (allBet / allWin > 5) {
                System.out.println(
"输了八成了");
                
if (rad > 98) {
                    
return getSteps(WIN_MAX);
                } 
else if (rad > 95) {
                    
return getSteps(OPEN_SONG_DENG);
                } 
else if (rad > 90) {
                    
return getSteps(OPEN_ONCE_MORE);
                } 
else if (rad > 30) {
                    
return getSteps(COMMON);
                } 
else {
                    
return getSteps(OPEN_LOSE);
                }
            } 
else if (allBet > allWin) {
                System.out.println(
"输了。。。。。。");
                
if (rad > 98) {
                    
return getSteps(WIN_MAX);
                } 
else if (rad > 95) {
                    
return getSteps(OPEN_SONG_DENG);
                } 
else if (rad > 90) {
                    
return getSteps(OPEN_ONCE_MORE);
                } 
else if (rad > 10) {
                    
return getSteps(COMMON);
                } 
else {
                    
return getSteps(OPEN_LOSE);
                }
            } 
else if (allBet < allWin) {
                System.out.println(
"赢了。。。。。。");
                
if (rad > 50) {
                    
return getSteps(OPEN_LOSE);
                } 
else {
                    
return getSteps(COMMON);
                }
            } 
else {
                System.out.println(
"出鬼了。。。。");
                
return getSteps(COMMON);
            }
        }
    }
}





尽管千里冰封
依然拥有晴空

你我共同品味JAVA的浓香.
posted on 2007-11-13 09:06 千里冰封 阅读(2685) 评论(0)  编辑  收藏 所属分类: JAVASE

只有注册用户登录后才能发表评论。


网站导航: