📄 computer.java
字号:
import java.util.Random;
public class Computer {
final int MY_HIST=0;
final int OPP_HIST=1;
final int BOTH_HIST=2;
final int scissors = 0; /*剪刀*/
final int rock = 1; /*石头*/
final int paper = 2; /*布*/
final int trials = 1000; /* number of turns per match */
final int will_beat[] = {1,2,0};
final int will_lose_to[] = {2,0,1};
final int ages[] = { 1000, 100, 10, 5, 2, 1 };
final int num_ages = 6;
final long maxrandom = 914748394; /* ratio range is 0 <= r < 1 */
/* Full History Structure (global variables, accessible to the
current player during each match)
- element 0 is the number of trials played so far
- element i is the action taken on turn i (1 <= i <= trials ) */
int my_history[] = new int[trials+1];//通过方法访问-玩家记录
int opp_history[] = new int[trials+1];//通过方法访问-电脑记录
class score {
int score = -1;
};
class move {
int move = -1;
};
class stats {
int sum[][] = new int[1 + trials][3];
int age;
};
class predict {
stats st=new stats();
int last;
};
class iocaine {
predict pr_history[][][] = new predict[num_ages][3][2];
predict pr_freq[][] = new predict[num_ages][2];
predict pr_fixed = new predict() ;
predict pr_random = new predict();
predict pr_meta[] = new predict[num_ages] ;
stats stats[] = new stats[2] ;
};
public void init() {//每局开始对记录列表初始化
my_history[0] = 0;
opp_history[0] = 0;
}
public void add_history(int a,int b) {//添加到记录列表
my_history[0] += 1;
opp_history[0] += 1;
my_history[my_history[0]] = a;
opp_history[opp_history[0]] = b;
}
public String statdata(int pr) {//统计对战结果pr==1输出百分比形式
double s,p,temp;//胜,负,平
int i;
s=p=0;
temp = my_history[0];
for(i =1;i<temp+1;++i){
if ((my_history[i]==1)&&(opp_history[i]==0)) s+=1;
if ((my_history[i]==2)&&(opp_history[i]==1)) s+=1;
if ((my_history[i]==0)&&(opp_history[i]==2)) s+=1;
if (opp_history[i]==my_history[i]) p+=1;
}
if (pr==0)
return (int)Math.rint(s)+"胜 "+(int)Math.rint((temp-s-p))+"负 "+(int)Math.rint(p)+"平";
else
return (int)Math.rint((s/temp)*100)+"%胜 "+(int)Math.rint(((temp-s-p)/temp)*100)+"%负 "+(int)Math.rint((p/temp)*100)+"%平";
}
public String whovoctor() {//判断胜利一方
int i;
i =my_history[0];
if ((my_history[i]==1)&&(opp_history[i]==0)) return "玩家胜利";
else if ((my_history[i]==2)&&(opp_history[i]==1)) return "玩家胜利";
else if ((my_history[i]==0)&&(opp_history[i]==2)) return "玩家胜利";
else if (opp_history[i]==my_history[i]) return "本局平局";
else return "电脑胜利";
}
int biased_roshambo (double prob_rock, double prob_paper){
/* roshambo with given probabilities of rock, paper, or scissors */
double thro1;
Random thro = new Random(maxrandom);
thro1 = thro.nextDouble();
if ( thro1 < prob_rock ) { return(rock); }
else if ( thro1 < prob_rock + prob_paper ) { return(paper); }
else /* throw >= prob_rock + prob_paper */ { return(scissors); }
}
//------------------------------------------------------------------------------
int match_single(int i,int num,int[] history) {
int highptr = num;
int lowptr = i;
while (lowptr > 0 && history[lowptr] == history[highptr]) --lowptr; --highptr;
return num - highptr;
}
int match_both(int i,int num) {
int j;
for (j = 0; j < i && opp_history[num-j] == opp_history[i-j]
&& my_history[num-j] == my_history[i-j]; ++j);
return j;
}
int[] do_history(int age) {
int num = my_history[0];
int best_length[]= new int[3],i,j,w;
int best[] = new int[3];
for (w = 0; w < 3; ++w) best[w] = best_length[w] = 0;
for (i = num - 1; i > num - age && i > best_length[MY_HIST]; --i) {
j = match_single(i,num,my_history);
if (j > best_length[MY_HIST]) {
best_length[MY_HIST] = j;
best[MY_HIST] = i;
if (j > num / 2) break;
}
}
for (i = num - 1; i > num - age && i > best_length[OPP_HIST]; --i) {
j = match_single(i,num,opp_history);
if (j > best_length[OPP_HIST]) {
best_length[OPP_HIST] = j;
best[OPP_HIST] = i;
if (j > num / 2) break;
}
}
for (i = num - 1; i > num - age && i > best_length[BOTH_HIST]; --i) {
j = match_both(i,num);
if (j > best_length[BOTH_HIST]) {
best_length[BOTH_HIST] = j;
best[BOTH_HIST] = i;
if (j > num / 2) break;
}
}
return best;
}
//---------------------------------统计处理-----------------------------------
void reset_stats( stats st) {//对数据结构初始化
int i;
st.age = 0;
for (i = 0; i < 3; ++i) st.sum[st.age][i] = 0;
}
void add_stats(stats st,int i,int delta) {//添加数据并加delta
st.sum[st.age][i] += delta;
}
void next_stats(stats st) {//指针移动到下一项,并复制上一记录数据
if (st.age < trials) {
int i;
++(st.age);
for (i = 0; i < 3; ++i)
st.sum[st.age][i] = st.sum[st.age - 1][i];
}
}
int max_stats( stats st,int age,score score) {
int i;
int which = -1;
for (i = 0; i < 3; ++i) {
int diff;
if (age > st.age)
diff = st.sum[st.age][i];
else
diff = st.sum[st.age][i] - st.sum[st.age - age][i];
if (diff > score.score) {
score.score = diff;
which = i;
}
}
return which;
}
//--------------------预测对方下一步行动---------------------------------------------
void reset_predict(predict pred) {
reset_stats(pred.st);
pred.last = -1;
}
/* last: opponent's last move (-1 if none)
| guess: algorithm's prediction of opponent's next move */
void do_predict(predict pred,int last,int guess) {//预测下一步
if ( last != -1) {
final int diff = (3 + last - pred.last) % 3;
add_stats(pred.st,will_beat[diff],1);
add_stats(pred.st,will_lose_to[diff],-1);
next_stats(pred.st);
}
pred.last = guess;
}
void scan_predict(predict pred,int age,move move,score score) {
int i = -1;
i = (max_stats(pred.st,age,score));
if (i!=-1) move.move = ((pred.last + i) % 3);
}
//----------------------------主函数---------------------------------------------------------
int iocaine( iocaine i) {
int num = my_history[0];
int last = (num > 0) ? opp_history[num] : -1;
int guess = biased_roshambo(1.0/3.0,1.0/3.0);
int w,a,p;
if (0 == num) {//对数据结构初始化
for (a = 0; a < num_ages; ++a) {
reset_predict(i.pr_meta[a]);
for (p = 0; p < 2; ++p) {
for (w = 0; w < 3; ++w)
reset_predict(i.pr_history[a][w][p]);
reset_predict(i.pr_freq[a][p]);
}
}
for (p = 0; p < 2; ++p) reset_stats(i.stats[p]);
reset_predict(i.pr_random);
reset_predict(i.pr_fixed);
} else {
add_stats(i.stats[0],my_history[num],1);
add_stats(i.stats[1],opp_history[num],1);
}
for (a = 0; a < num_ages; ++a) {//做预测计算
int best[]= new int[3];
best = do_history(ages[a]);
for (w = 0; w < 3; ++w) {
int b = best[w];
if (0 == b) {
do_predict(i.pr_history[a][w][0],last,guess);
do_predict(i.pr_history[a][w][1],last,guess);
continue;
}
do_predict(i.pr_history[a][w][0],last,my_history[b+1]);
do_predict(i.pr_history[a][w][1],last,opp_history[b+1]);
}
for (p = 0; p < 2; ++p) {
int freq=-1;
score score2=new score();
freq=max_stats(i.stats[p],ages[a],score2);
if (freq!=-1)
do_predict(i.pr_freq[a][p],last,freq);
else
do_predict(i.pr_freq[a][p],last,guess);
}
}
do_predict(i.pr_random,last,guess);
do_predict(i.pr_fixed,last,0);
for (a = 0; a < num_ages; ++a) {
int aa;
score score=new score();
move move = new move();
for (aa = 0; aa < num_ages; ++aa) {
for (p = 0; p < 2; ++p) {
for (w = 0; w < 3; ++w)
scan_predict(i.pr_history[aa][w][p],
ages[a],move,score);
scan_predict(i.pr_freq[aa][p],ages[a],move,score);
}
}
scan_predict(i.pr_random,ages[a],move,score);
scan_predict(i.pr_fixed,ages[a],move,score);
do_predict(i.pr_meta[a],last,move.move);
}
{
score score1=new score();
move move1 = new move();
for (a = 0; a < num_ages; ++a)
scan_predict(i.pr_meta[a],trials,move1,score1);
return move1.move;
}
}
int iocainebot()
{
int i,j;
iocaine p= new iocaine();
for (i=0;i <num_ages; ++i)//分配空间
for (j=0;j <3; ++j){
p.pr_history[i][j][0] = new predict();
p.pr_history[i][j][1] = new predict();
}
for (i=0;i <num_ages; ++i){
p.pr_freq[i][0] = new predict();
p.pr_freq[i][1] = new predict();
}
for (i=0;i <num_ages; ++i){
p.pr_meta[i] = new predict();
p.pr_meta[i] = new predict();
}
p.stats[0]=new stats();
p.stats[1]=new stats();
return iocaine(p);//返回计算结果
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -