Last active
August 29, 2015 14:04
-
-
Save wkcn/ae5a4a1402d665c809f5 to your computer and use it in GitHub Desktop.
RPS TEST
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<vector> | |
#include<iostream> | |
#include<string> | |
#include <algorithm> | |
using namespace std; | |
namespace RPS | |
{ | |
enum state { rock = 0, paper = 1, scissors = 2, blank = 3 }; | |
struct player | |
{ | |
virtual ~player( ) { } | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) = 0; | |
}; | |
} | |
#define MAX_MEMORY 5239 | |
using namespace RPS; | |
enum resultState { LOSE = 0, BALANCE = 1, WIN = 2}; | |
struct RecorderChild | |
{ | |
state Me; | |
state You; | |
void Set(state me,state you) | |
{ | |
Me = me;You = you; | |
} | |
}; | |
state CorrectX(state s,int n) | |
{ | |
int i=s; | |
i+=n; | |
int j=i/3; | |
i -= j*3; | |
while(i<0)i+=3; | |
while(i>2)i-=3; | |
return state(i); | |
} | |
class Recorder | |
{ | |
private: | |
int pointer; | |
bool full; | |
public: | |
RecorderChild r[MAX_MEMORY]; | |
unsigned int MyRec[4]; | |
unsigned int YourRec[4]; | |
RecorderChild& Get(int id) | |
{ | |
int p = pointer-id; | |
if(p<0)p+=MAX_MEMORY; | |
return r[p]; | |
} | |
void Push(state me,state you) | |
{ | |
if(pointer==MAX_MEMORY)full = true; | |
MyRec[me]++; | |
YourRec[you]++; | |
pointer %= MAX_MEMORY; | |
r[pointer].Set(me,you); | |
pointer ++;//指向下一空挡 | |
} | |
Recorder():pointer(0),full(0){ | |
for(int i=0;i<4;i++) | |
{ | |
MyRec[i]=0; | |
YourRec[i]=0; | |
} | |
}; | |
}; | |
resultState Judge(state me,state you) | |
{ | |
if (me == you) return BALANCE; | |
if (me == rock && you == paper) return LOSE; | |
if (me == paper && you == scissors) return LOSE; | |
if (me == scissors && you == rock) return LOSE; | |
return WIN; | |
}; | |
struct Step | |
{ | |
int step;//0~729 | |
int StepStandard(Recorder &w,int k = 0) | |
{ | |
RecorderChild &a = w.Get(k+0); | |
RecorderChild &b = w.Get(k+1); | |
RecorderChild &c = w.Get(k+2); | |
int array[6] = {a.Me,a.You,b.Me,b.You,c.Me,c.You}; | |
int o = array[0]; | |
int t = 1; | |
step = 0; | |
for(int i=5;i>0;i--) | |
{ | |
array[i]-=o; | |
if(array[i]<0)array[i]+=3; | |
step += t * array[i]; | |
t *= 3; //3进制 | |
} | |
return o; | |
} | |
}; | |
struct Strategy | |
{ | |
state hope[3];//按期望从高到低排序!!! | |
Strategy() | |
{ | |
hope[0] = rock; | |
hope[1] = paper; | |
hope[2] = scissors; | |
} | |
template <class T> | |
void Sort(T *rec) | |
{ | |
int t[3]={rec[0],rec[1],rec[2]}; | |
hope[0] = rock; | |
hope[1] = paper; | |
hope[2] = scissors; | |
for (int j=0;j<3;j++) | |
{ | |
for (int k=0;k<3-j;k++) | |
{ | |
if(t[j]<t[k]) | |
{ | |
int o=t[j];t[j]=t[k];t[k]=o; | |
state s=hope[j];hope[j]=hope[k];hope[k]=s; | |
} | |
} | |
} | |
} | |
void Solve() | |
{ | |
for(int s=0;s<3;s++) | |
{ | |
hope[s]=CorrectX(hope[s],1); | |
} | |
} | |
void Correct(int o) | |
{ | |
for(int s=0;s<3;s++) | |
{ | |
hope[s] = CorrectX(hope[s],o); | |
} | |
} | |
}; | |
state protect(Strategy *s)//比较0与1 | |
{ | |
return (Judge(state(s->hope[0]),state(s->hope[1]))==WIN)?state(s->hope[0]):state(s->hope[1]); | |
} | |
struct mData | |
{ | |
//+3偏移 | |
int d[7]; | |
void Push(int o) | |
{ | |
d[o+3]++; | |
} | |
bool Available(int total) | |
{ | |
int maxn=0; | |
int mid=0; | |
for (int i=0;i<7;i++) | |
{ | |
if (mid<d[i]) | |
{ | |
if (maxn<d[i]) | |
{ | |
maxn=d[i]; | |
} | |
else | |
{ | |
mid=d[i]; | |
} | |
} | |
} | |
return (((maxn-mid)>(total/2))||(maxn>total-10)); | |
} | |
int GetE() | |
{ | |
int maxn=0; | |
for (int i=0;i<7;i++) | |
{ | |
if (maxn<d[i]) | |
{ | |
maxn=d[i]; | |
} | |
} | |
return maxn; | |
} | |
int GetOffset() | |
{ | |
int maxn=0; | |
int o; | |
int mid=0; | |
for (int i=0;i<7;i++) | |
{ | |
if (mid<d[i]) | |
{ | |
if (maxn<d[i]) | |
{ | |
maxn=d[i]; | |
o=i; | |
} | |
else | |
{ | |
mid=d[i]; | |
} | |
} | |
} | |
return o-3; | |
} | |
mData() | |
{ | |
for (int i=0;i<7;i++) | |
{ | |
d[i]=0; | |
} | |
} | |
}; | |
struct expData | |
{ | |
state yourState;//对方状态 | |
bool balance; | |
expData() | |
{ | |
balance = true; | |
yourState = blank; | |
} | |
}; | |
struct mirai_player : public player | |
{ | |
mData recData[2][3]; | |
int game; | |
int cute; | |
int val; | |
Recorder recorder; | |
Step stepTest; | |
expData exp[730];//[3]; | |
state considerHope; | |
state testStepState; | |
int testStepID; | |
state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) | |
{ | |
//已进行局数,当前+1局 | |
game = self_history.size(); | |
if (game == 0){ | |
char mirai[16]="I like Miku"; | |
return state( (mirai[3]*mirai[9]) % 3); | |
} | |
if(cute != game-1) | |
{ | |
cute = game-1; | |
if(opponent_history[cute] != blank) | |
{ | |
//记录上一局局势 | |
recorder.Push(self_history[cute],opponent_history[cute]); | |
val++; | |
state lastYou =opponent_history[cute]; | |
//模拟 | |
Strategy tempSt; | |
tempSt.Sort(recorder.MyRec); | |
recData[0][0].Push(lastYou - tempSt.hope[0]); | |
recData[0][1].Push(lastYou - tempSt.hope[1]); | |
recData[0][2].Push(lastYou - tempSt.hope[2]); | |
tempSt.Sort(recorder.YourRec); | |
recData[1][0].Push(lastYou - tempSt.hope[0]); | |
recData[1][1].Push(lastYou - tempSt.hope[1]); | |
recData[1][2].Push(lastYou - tempSt.hope[2]); | |
//遍历寻找最优解 | |
int bx=0,by=0; | |
int e=-1,teste; | |
for (int x=0;x<2;x++) | |
{ | |
for (int y=0;y<3;y++) | |
{ | |
teste = recData[x][y].GetE(); | |
if (e<teste) | |
{ | |
e=teste; | |
bx = x;by =y; | |
} | |
} | |
} | |
//模拟当前状态 | |
if (recData[bx][by].Available(game)) | |
{ | |
Strategy hope; | |
state otherthink; | |
if (bx==0) | |
{ | |
hope.Sort(recorder.MyRec); | |
otherthink = CorrectX(hope.hope[by],recData[bx][by].GetOffset()+1); | |
} | |
else | |
{ | |
hope.Sort(recorder.YourRec); | |
otherthink = CorrectX(hope.hope[by],recData[bx][by].GetOffset()+1); | |
} | |
considerHope = otherthink; | |
} | |
if (val>4) | |
{ | |
int o = stepTest.StepStandard(recorder,2); | |
int n = self_history.size()-1; | |
resultState lastState = Judge(self_history[n],opponent_history[n]); | |
state m = self_history[n]; | |
m = CorrectX(m,-o); | |
int step = stepTest.step; | |
if (lastState == LOSE) | |
{ | |
if (exp[step].balance) | |
{ | |
exp[step].yourState = m; | |
exp[step].balance = false; | |
} | |
else | |
{ | |
exp[step].yourState = CorrectX(exp[step].yourState,1);//弱一位 | |
} | |
} | |
if (lastState == BALANCE) | |
{ | |
/* | |
if (exp[step].balance) | |
{ | |
exp[step].yourState = m; | |
//exp[step].yourState = CorrectX(m,-1); | |
} | |
else | |
{ | |
//exp[step].yourState = CorrectX(m,-1); | |
//exp[step].yourState = CorrectX(exp[step].yourState,1);//弱一位 | |
}*/ | |
if (testStepState != blank) | |
{ | |
exp[testStepID].yourState = CorrectX(testStepState,0); | |
} | |
} | |
} | |
} | |
} | |
//启用EXP | |
if (val>3) | |
{ | |
int o = stepTest.StepStandard(recorder,1); | |
int step = stepTest.step; | |
//似曾相识 | |
if (exp[step].yourState!=blank) | |
{ | |
testStepState = CorrectX(exp[step].yourState,o+1); | |
testStepID = step; | |
return testStepState; | |
} | |
} | |
return considerHope; | |
} | |
mirai_player():cute(-1),val(0),testStepState(blank){}; | |
}; | |
struct rock_player : public player | |
{ | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) { | |
//if(self_history.size()<5)return rock; | |
return rock; | |
//return CorrectX(opponent_history[opponent_history.size()-3],2);//state(rand()%3); | |
//return state(rand()%3); | |
//return rock; | |
} | |
}; | |
struct scissors_player : public player | |
{ | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) { | |
return scissors; | |
} | |
}; | |
struct paper_player : public player | |
{ | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) { | |
return paper; | |
} | |
}; | |
struct random_player : public player | |
{ | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) { | |
return state(rand()%3); | |
} | |
}; | |
struct reg_player : public player | |
{ | |
int i,b; | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) { | |
i++; | |
b=i%100; | |
if(b<70)return rock; | |
if(b>90)return paper; | |
return scissors; | |
} | |
reg_player():i(0){}; | |
}; | |
struct tim_player : public player | |
{ | |
int i,b; | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) { | |
i++; | |
b=i%3; | |
if(b==1)return rock; | |
if(b==0)return paper; | |
return scissors; | |
} | |
tim_player():i(0){}; | |
}; | |
struct emuMe_player : public player | |
{ | |
int i,j; | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) { | |
if(self_history.size()<10)return rock; | |
return CorrectX(opponent_history[opponent_history.size()-i],j);//state(rand()%3); | |
} | |
void Set(int _i,int _j){i=_i;j=_j;}; | |
}; | |
struct emuYou_player : public player | |
{ | |
int i,j; | |
virtual state play( std::size_t milisecond_left, const std::vector< state > & self_history, const std::vector< state > & opponent_history ) { | |
if(self_history.size()<10)return rock; | |
return CorrectX(self_history[self_history.size()-i],j);//state(rand()%3); | |
} | |
void Set(int _i,int _j){i=_i;j=_j;}; | |
}; | |
#define TOTAL 39000 | |
string Trans(state p1) | |
{ | |
if(p1==rock)return "石头"; | |
if(p1==paper)return "布"; | |
if(p1==scissors)return "剪刀"; | |
return ""; | |
} | |
int win,ban; | |
void printX(int i,state p1,state p2,bool view = true) | |
{ | |
string r="失败"; | |
if (Judge(p1,p2)==WIN){r="胜利";win++;} | |
if (Judge(p1,p2)==BALANCE){r="平局";ban++;} | |
//if (judge(p1,p2)==WIN){r="胜利";win++;} | |
if(view)cout<<"第"<<i<<"局\t\t"<<Trans(p1)<<" VS "<<Trans(p2)<<" "<<r<<endl; | |
} | |
void Test(player *playerMe,player *playerYou,bool view) | |
{ | |
win = 0; ban = 0; | |
vector<state> me_history,you_history; | |
for(int i=1;i<TOTAL;i++) | |
{ | |
state p1 = playerMe->play(TOTAL-i,me_history,you_history); | |
state p2 = playerYou->play(TOTAL-i,you_history,me_history); | |
printX(i,p1,p2,view); | |
me_history.push_back(p1); | |
you_history.push_back(p2); | |
} | |
cout<<endl<<endl<<"胜利局数: "<<win<<endl; | |
cout<<endl<<endl<<"平局局数: "<<ban<<endl; | |
cout<<endl<<endl<<"失败局数 "<<TOTAL-win-ban<<endl; | |
cout<<"胜率: "<<win*1.0/TOTAL<<endl; | |
cout<<"平局率: "<<ban*1.0/TOTAL<<endl; | |
} | |
int main() | |
{ | |
//mirai_player playerMe; | |
//rock_player playerYou; | |
player *p1; | |
player *p2; | |
cout<<TOTAL<<"局 PK 大赛"<<endl<<endl; | |
if(0) | |
{ | |
cout<<"开始与RockPlayer PK"<<endl; | |
p1 = new mirai_player; | |
p2 = new rock_player; | |
Test(p1,p2,0); | |
cout<<endl; | |
delete p1; | |
delete p2; | |
} | |
if(0) | |
{ | |
cout<<"开始与RaperPlayer PK"<<endl; | |
p1 = new mirai_player; | |
p2 = new paper_player; | |
Test(p1,p2,0); | |
cout<<endl; | |
delete p1; | |
delete p2; | |
} | |
if(0) | |
{ | |
cout<<"开始与ScissorsPlayer PK"<<endl; | |
p1 = new mirai_player; | |
p2 = new scissors_player; | |
Test(p1,p2,0); | |
cout<<endl; | |
delete p1; | |
delete p2; | |
} | |
if(0) | |
{ | |
cout<<"开始与RandomPlayer PK"<<endl; | |
p1 = new mirai_player; | |
p2 = new random_player; | |
Test(p1,p2,0); | |
cout<<endl; | |
delete p1; | |
delete p2; | |
} | |
if(0) | |
{ | |
//p2 = new emuMe_player; | |
emuMe_player p3; | |
p1 = new mirai_player; | |
cout<<"开始与emuMe PK"<<endl; | |
for(int i=1;i<8;i++) | |
{ | |
for (int j=0;j<3;j++) | |
{ | |
p3.Set(i,j); | |
Test(p1,&p3,0); | |
cout<<endl; | |
} | |
} | |
delete p1; | |
} | |
if(1) | |
{ | |
//p2 = new emuMe_player; | |
emuYou_player p3; | |
p1 = new mirai_player; | |
cout<<"开始与emuYou PK"<<endl; | |
for(int i=1;i<8;i++) | |
{ | |
for (int j=0;j<3;j++) | |
{ | |
p3.Set(i,j); | |
Test(p1,&p3,0); | |
cout<<endl; | |
} | |
} | |
delete p1; | |
} | |
if(0) | |
{ | |
cout<<"开始与RegPlayer PK"<<endl; | |
p1 = new mirai_player; | |
p2 = new reg_player; | |
Test(p1,p2,0); | |
cout<<endl; | |
delete p1; | |
delete p2; | |
} | |
if(0) | |
{ | |
cout<<"开始与TimPlayer PK"<<endl; | |
p1 = new mirai_player; | |
p2 = new tim_player; | |
Test(p1,p2,1); | |
cout<<endl; | |
delete p1; | |
delete p2; | |
} | |
system(" pause "); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment