Skip to content

Instantly share code, notes, and snippets.

@wkcn
Last active August 29, 2015 14:04
Show Gist options
  • Save wkcn/ae5a4a1402d665c809f5 to your computer and use it in GitHub Desktop.
Save wkcn/ae5a4a1402d665c809f5 to your computer and use it in GitHub Desktop.
RPS TEST
#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