ZJOI2014 2048
Description
提交答案题,写个2048 AI 告诉你随机数生成方式.
Sol
xjblg+A*.
首先我写了个模拟,2048.
然后自己YY就可以啦...各种乱搞...
因为随机数,一个最好的状态一定只由一种状态得到,但最初的状态可能转移到多个价值差不多的状态,需要多搜几个..
于是我用队列来卡队列大小...剩下的就是估价函数了.
写估价函数的时候一个蛇形递增的序列权值必然需要很高.
最大权值也有一定权值,因为毕竟要合起来,但是合起来又不一定是最优的,价值适当.
我自己还乱搞了几个,比如空格子个数,相邻相同数字的个数,这个多了可以一步全部合起来来获得更多的空格子.
然后把2048的大模拟封装成结构体写头文件里,表示一个状态.
最后就是跑了...32768应该都可以跑出来,而且比较快,开 O2 跑的更快.
某ISA还把数据加强了,要求跑出65534,我说这个也是可以的,不确定每个种子都能跑出来,不过大部分应该是可以跑出来的.
剩下的就是贴代码了...
Code
2048.cpp
#include<cstdio>
#include<conio.h>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std; const int N = 4;
const int M = 16;
const int MUL = 8221; int seq;
int w[M];
FILE *fout=fopen("log.out","w"); void initSeed(int seed){ seq = seed; }
int GetRand(){ return (seq = (seq * MUL) + (seq >> 16)) & 15; }
//1 w 2 s 3 a 4 d
int Read(char ch=getch()){
if(isascii(ch)){
switch(ch){
case 'w':case 'W':return 1;
case 's':case 'S':return 2;
case 'a':case 'A':return 3;
case 'd':case 'D':return 4;
}
}else{
ch=getch();
switch(ch){
case 72:return 1;
case 75:return 3;
case 77:return 4;
case 80:return 2;
}
}return -1;
}
void GetW(int x=GetRand()){ for(;w[x];x=GetRand());w[x]=2; }
void Up(int a[]){
int u[5],b[5];
for(int i=0,j,c,t;i<4;i++){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i;j<16;j+=4) if(a[j]) b[++c]=a[j],a[j]=0;
for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
for(j=1,t=i;j<=c;j++) if(!u[j]) a[t]=b[j],t+=4;
}
}
void Down(int a[]){
int u[5],b[5];
for(int i=0,j,c,t;i<4;i++){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i+12;j>=0;j-=4) if(a[j]) b[++c]=a[j],a[j]=0;
for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
for(j=1,t=i+12;j<=c;j++) if(!u[j]) a[t]=b[j],t-=4;
}
}
void Left(int a[]){
int u[5],b[5];
for(int i=0,j,c,t;i<16;i+=4){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i;j<i+4;j++) if(a[j]) b[++c]=a[j],a[j]=0;
for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
for(j=1,t=i;j<=c;j++) if(!u[j]) a[t]=b[j],t++;
}
}
void Right(int a[]){
int u[5],b[5];
for(int i=0,j,c,t;i<16;i+=4){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i+3;j>=i;j--) if(a[j]) b[++c]=a[j],a[j]=0;
for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
for(j=1,t=i+3;j<=c;j++) if(!u[j]) a[t]=b[j],t--;
}
} void Copy(int a[],int b[]){ for(int i=0;i<16;i++) b[i]=a[i]; }
int check(int a[],int b[]){ for(int i=0;i<16;i++) if(a[i]!=b[i]) return 1;return 0; } void Out(){
system("cls");
for(int i=1;i<=8;i++) putchar('\n');
for(int i=0;i<M;i++){
if(!w[i]) printf(" -%c"," \n"[(i+1)%4 == 0]);
else printf("%5d%c",w[i]," \n"[(i+1)%4 == 0]);
}
}
int Over(){
int t[M];
Copy(w,t),Up(t);if(check(w,t)) return 0;
Copy(w,t),Down(t);if(check(w,t)) return 0;
Copy(w,t),Left(t);if(check(w,t)) return 0;
Copy(w,t),Right(t);if(check(w,t)) return 0;
return 1;
}
void Print(char c){ fprintf(fout,"%c",c); }
void Play(int x){
initSeed(x),GetW(),GetW(),Out();
int cp[M];
for(;;){
int od=Read(),f=0;
switch(od){
case 1:Copy(w,cp),Up(cp);if(check(w,cp)) Up(w),f=1,Print('U');break;
case 2:Copy(w,cp),Down(cp);if(check(w,cp)) Down(w),f=1,Print('D');break;
case 3:Copy(w,cp),Left(cp);if(check(w,cp)) Left(w),f=1,Print('L');break;
case 4:Copy(w,cp),Right(cp);if(check(w,cp)) Right(w),f=1,Print('R');break;
}
if(f) GetW();
if(!Over()) Out();
else{ puts("You lose!");return; }
}
}
int main(){
for(int x;;){
cin>>x;
Play(x);
}return 0;
}
_2048.h
#include<cstdio>
#include<conio.h>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std; #define G(i,j) ((i-1)*4+j-1)
const int N = 4;
const int M = 16;
const int MUL = 8221;
const double SmoothVal = 17;
const double MonoVal = 100;
const double SpaceVal = 5;
const double MaxVal = 3; struct S{
int seq,maxn,lst;double val;
int w[M];
//1 w 2 s 3 a 4 d
void initSeed(int seed){ seq = seed;memset(w,0,sizeof(w)); }
int GetRand(){ return (seq = (seq * MUL) + (seq >> 16)) & 15; }
void GetW(){ int x=GetRand();for(;w[x];x=GetRand());w[x]=2; }
void Up(int a[]){
int u[5],b[5];
for(int i=0,j,c,t;i<4;i++){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i;j<16;j+=4) if(a[j]) b[++c]=a[j],a[j]=0;
for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
for(j=1,t=i;j<=c;j++) if(!u[j]) a[t]=b[j],t+=4;
}
}
void Down(int a[]){
int u[5],b[5];
for(int i=0,j,c,t;i<4;i++){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i+12;j>=0;j-=4) if(a[j]) b[++c]=a[j],a[j]=0;
for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
for(j=1,t=i+12;j<=c;j++) if(!u[j]) a[t]=b[j],t-=4;
}
}
void Left(int a[]){
int u[5],b[5];
for(int i=0,j,c,t;i<16;i+=4){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i;j<i+4;j++) if(a[j]) b[++c]=a[j],a[j]=0;
for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
for(j=1,t=i;j<=c;j++) if(!u[j]) a[t]=b[j],t++;
}
}
void Right(int a[]){
int u[5],b[5];
for(int i=0,j,c,t;i<16;i+=4){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i+3;j>=i;j--) if(a[j]) b[++c]=a[j],a[j]=0;
for(j=1;j<=c;j++) if(!u[j] && b[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1;
for(j=1,t=i+3;j<=c;j++) if(!u[j]) a[t]=b[j],t--;
}
}
void Find(){
maxn=lst=0;
for(int i=0;i<M;i++) if(w[i]) lst++,maxn=max(w[i],maxn);
}
void Copy(int a[],int b[]){ for(int i=0;i<M;i++) b[i]=a[i]; }
int check(int a[],int b[]){ for(int i=0;i<M;i++) if(a[i]!=b[i]) return 1;return 0; }
int Over(){
int t[M];
Copy(w,t),Up(t);if(check(w,t)) return 0;
Copy(w,t),Down(t);if(check(w,t)) return 0;
Copy(w,t),Left(t);if(check(w,t)) return 0;
Copy(w,t),Right(t);if(check(w,t)) return 0;
return 1;
}
void Order(int x){
switch(x){
case 1:Up(w);break;
case 2:Down(w);break;
case 3:Left(w);break;
case 4:Right(w);break;
}
}
void Print(){
for(int i=0;i<M;i++)
if(!w[i]) printf(" -%c"," \n"[(i+1)%4 == 0]);
else printf("%5d%c",w[i]," \n"[(i+1)%4 == 0]);
putchar('\n');
}
int abs(int x){ return x<0?-x:x; }
int Smooth(){
int res=0x7fffffff,tmp=0;
int b1[]={ 0,1,2,3,7,6,5,4,8,9,10,11,15,14,13,12 };
int b2[]={ 3,2,1,0,4,5,6,7,11,10,9,8,12,13,14,15 };
int b3[]={ 12,13,14,15,11,10,9,8,4,5,6,7,3,2,1,0 };
int b4[]={ 15,14,13,12,8,9,10,11,7,6,5,4,0,1,2,3 };
int b5[]={ 0,4,8,12,13,9,5,1,2,6,10,14,15,11,7,3 };
int b6[]={ 12,8,4,0,1,5,9,13,14,10,6,2,3,7,11,15 };
int b7[]={ 3,7,11,15,14,10,6,2,1,5,9,13,12,8,4,0 };
int b8[]={ 15,11,7,3,2,6,10,14,13,9,5,1,0,4,8,12 }; for(int i=0;i<M-1;i++) if(w[b1[i]] && w[b1[i+1]]) tmp+=abs(w[b1[i]]-w[b1[i+1]]*2);
if(w[b1[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
for(int i=0;i<M-1;i++) if(w[b2[i]] && w[b2[i+1]]) tmp+=abs(w[b2[i]]-w[b2[i+1]]*2);
if(w[b2[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
for(int i=0;i<M-1;i++) if(w[b3[i]] && w[b3[i+1]]) tmp+=abs(w[b3[i]]-w[b3[i+1]]*2);
if(w[b3[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
for(int i=0;i<M-1;i++) if(w[b4[i]] && w[b4[i+1]]) tmp+=abs(w[b4[i]]-w[b4[i+1]]*2);
if(w[b4[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
for(int i=0;i<M-1;i++) if(w[b5[i]] && w[b5[i+1]]) tmp+=abs(w[b5[i]]-w[b5[i+1]]*2);
if(w[b5[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
for(int i=0;i<M-1;i++) if(w[b6[i]] && w[b6[i+1]]) tmp+=abs(w[b6[i]]-w[b6[i+1]]*2);
if(w[b6[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
for(int i=0;i<M-1;i++) if(w[b7[i]] && w[b7[i+1]]) tmp+=abs(w[b7[i]]-w[b7[i+1]]*2);
if(w[b7[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
for(int i=0;i<M-1;i++) if(w[b8[i]] && w[b8[i+1]]) tmp+=abs(w[b8[i]]-w[b8[i+1]]*2);
if(w[b8[0]] == maxn) tmp-=maxn;res=min(res,tmp),tmp=0;
return res;
// for(int i=1;i<=4;i++) for(int j=1;j<=3;j++) if(w[G(i,j)] && w[G(i,j+1)] && w[G(i,j)] > w[G(i,j+1)]) tmp+=w[G(i,j)]-w[G(i,j+1)]*2;
// res=min(res,tmp),tmp=0;
// for(int i=1;i<=4;i++) for(int j=1;j<=3;j++) if(w[G(i,j)] && w[G(i,j+1)] && w[G(i,j)] < w[G(i,j+1)]) tmp+=w[G(i,j+1)]-w[G(i,j)]*2;
// res=min(res,tmp),tmp=0;
// for(int j=1;j<=4;j++) for(int i=1;i<=3;i++) if(w[G(i,j)] && w[G(i+1,j)] && w[G(i,j)] > w[G(i+1,j)]) tmp+=w[G(i,j)]-w[G(i+1,j)]*2;
// res=min(res,tmp),tmp=0;
// for(int j=1;j<=4;j++) for(int i=1;i<=3;i++) if(w[G(i,j)] && w[G(i+1,j)] && w[G(i,j)] < w[G(i+1,j)]) tmp+=w[G(i+1,j)]-w[G(i,j)]*2;
// return min(res,tmp);
}
int Mono(){
int res=0,tmp=0;
for(int i=1;i<=4;i++) for(int j=1;j<=3;j++) if(w[G(i,j)] < w[G(i,j+1)]) tmp++;
for(int i=1;i<=4;i++) for(int j=1;j<=3;j++) if(w[G(i,j)] > w[G(i,j+1)]) tmp--;
if(tmp < 0) tmp*=-1;
for(int j=1;j<=4;j++) for(int i=1;i<=3;i++) if(w[G(i,j)] < w[G(i+1,j)]) res++;
for(int j=1;j<=4;j++) for(int i=1;i<=3;i++) if(w[G(i,j)] > w[G(i+1,j)]) res--;
if(res < 0) res*=-1;
return max(res,tmp);
}
int Space(){
int cnt=0;double r=0,h=0,sr=0,sh=0;
for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(!w[G(i,j)]) sr+=i,sh+=j,cnt++;
sr=sr/cnt,sh=sh/cnt;
for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(!w[G(i,j)]) r+=(sr-i)*(sr-i),h+=(sh-j)*(sh-j);
return (int)(r+h)*(16-lst);
}
void GetVal(){
val = 0;
val -= Smooth() * SmoothVal;
val += Mono() * MonoVal;
val -= Space() * SpaceVal;
val += maxn * MaxVal;
/* int u[5],b[5];
for(int i=0,j,c;i<4;i++){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i;j<16;j+=4) if(w[j]) b[++c]=w[j];
for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1,tmp+=b[j];
}
val=max(val,tmp),tmp=0;
for(int i=0,j,c;i<4;i++){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i+12;j>=0;j-=4) if(w[j]) b[++c]=w[j];
for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1,tmp+=b[j];
}
val=max(val,tmp),tmp=0;
for(int i=0,j,c;i<16;i+=4){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i;j<i+4;j++) if(w[j]) b[++c]=w[j];
for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1,tmp+=b[j];
}
val=max(val,tmp),tmp=0;
for(int i=0,j,c;i<16;i+=4){
memset(u,0,sizeof(u)),memset(b,0,sizeof(b));
for(c=0,j=i+3;j>=i;j--) if(w[j]) b[++c]=w[j];
for(j=1;j<=c;j++) if(!u[j]) if(b[j] == b[j+1]) b[j]+=b[j+1],u[j+1]=1,tmp+=b[j];
}*/
return;
}
};
main.cpp
#include "_2048.h"
#include<utility>
#include<vector>
#include<windows.h>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std; #define mpr(a,b) make_pair(a,b)
const int Q = 2048; queue<S> q;
vector<pair<int,int> > f;
int cnt; void Out(int x){
stack<int> stk;
// cout<<x<<endl;
for(pair<int,int> y=f[x];;y=f[y.first]){
stk.push(y.second);
// cout<<y.second<<endl;
if(y.first == 0) break;
}
for(;!stk.empty();stk.pop()){
switch(stk.top()){
case 1:putchar('U');break;
case 2:putchar('D');break;
case 3:putchar('L');break;
case 4:putchar('R');break;
}
}
}
void BFS(S &a){
q.push(a);int tmp=0;
f.push_back(mpr(0,0));
for(S t,s[5];!q.empty();++tmp){
// Sleep(120);
t=q.front(),q.pop();
// t.Print();
if(t.Find(),t.maxn >= 60000){ Out(tmp);return; }
if(t.Over()) continue; vector<pair<double,int> > A; for(int i=1;i<=4;i++){
s[i].initSeed(t.seq);
s[i].Copy(t.w,s[i].w);
s[i].Order(i);
if(!s[i].check(s[i].w,t.w)){ continue; }
s[i].Find();
// if(s[i].maxn >= 60000){ Out(tmp);cout<<i<<endl;return; }
if(s[i].Over()) continue;
s[i].GetW();
if(s[i].Over()) continue;
s[i].GetVal();
A.push_back(mpr(s[i].val,i));
// s[i].Print();
// q.push(s[i]);
// f.push_back(mpr(tmp,i));
} sort(A.begin(),A.end());
for(int i=A.size()-1;i>=0 && q.size()<Q && i+3>A.size();i--){
q.push(s[A[i].second]);
// s[A[i].second].Print(),printf("%lf\n",s[A[i].second].val);
f.push_back(mpr(tmp,A[i].second));
}
// cout<<"***********"<<endl;
// for(int i=A.size()-1;i>=0;i--) s[A[i].second].Print(),printf("%lf\n",s[A[i].second].val);
// cout<<"***********"<<endl;
}
} int main(){
freopen("204820.out","w",stdout);
S fff;
fff.initSeed(20);
fff.GetW(),fff.GetW();
// fff.Print();
BFS(fff);
return 0;
}
ZJOI2014 2048的更多相关文章
- ZJOI2017 Day1
私のZJOI Day1 2017-3-21 07:52:53 有人在暴力膜 苟-- 富贵 无相忘 ZJOI2017交流群 133135071 如果你足够厉害 如果你足够厉害 如果你足够厉害 其实完全可 ...
- jQuery实践-网页版2048小游戏
▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...
- android 模拟2048
利用节日休息时间在ANDROID上进行学习并模拟2048游戏. 效果如下图: 制作思路: 1.画出2048游戏主界面,根据手机屏幕宽高度进行计算并画出每个方块的大小. @Override protec ...
- 2048游戏_QT实现
#ifndef GAMEWIDGET_H #define GAMEWIDGET_H #include <QWidget> #include <QMouseEvent> #inc ...
- BZOJ 2048 题解
2048: [2009国家集训队]书堆 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1076 Solved: 499[Submit][Status ...
- flash跨域访问,crossdomain.xml,error #2048
最近遇到了flash的万年老梗,跨域访问的问题.之前一直没有处理过这类问题,是因为做项目的时候别人已经处理好了.真到自己遇到的时候,还是很费脑筋的. 1遇到的问题 客户端发布到网页的时候,socket ...
- 用javascript实现一个2048游戏
早就想自己写一个2048游戏了,昨晚闲着没事,终于写了一个 如下图,按方向键开始玩吧. 如果觉得操作不方便,请直接打开链接玩吧: http://gujianbo.1kapp.com/2048/2048 ...
- <2048>调查报告心得与体会
老师这次给我们布置了一个任务,就是让我们写一份属于自己的调查报告,针对这个任务,我们小组的六个人通过积极的讨论,提出了一些关于我们产品的问题,当然这些问题并不是很全面,因为我们是从自己的角度出发,无法 ...
- 【水】基于ege的2048
不要问我ege怎么装 http://tieba.baidu.com/p/2227018541 好,现在我们装好了ege 开始写2048吧 没有算法,单纯模拟,不用讲解——这才叫[水]的含义 界面极度简 ...
随机推荐
- Linux版MonoDevelop无法连接调试器的解决方案(Could not connet to the debugger)
安装了Linux版本的MonoDevelop之后,在运行程序的时候会提示Could not connnet to the debugger.的错误. 原因是新版本的Gnome Terminal不再接受 ...
- 以全局监听的方式处理img的error事件
http://www.ovaldi.org/2015/09/11/%E4%BB%A5%E5%85%A8%E5%B1%80%E7%9B%91%E5%90%AC%E7%9A%84%E6%96%B9%E5% ...
- Java中符号位扩展
第一个例子: byte b=-100;b在内存中是以补码的形式存贮的:1001 1100 如果执行char c=(char)b;如3楼企鹅先生所说:b要先变为int,这时增加的位全要用b的符号位填充( ...
- windows 杂项
农企amd的Radeon: 蓝宝石-镭 显卡m330只是 m200的马甲版本, nvidia的Geforce: ge: geometry : 几何很强, 精视 radeon倾向于单精度浮点计算很强, ...
- 理解button标签的默认行为
button标签的作用和它的名字一样,在绝大多数场合当做按钮来使用. 很多人在使用button按钮的时候出现过这样或者那样的问题,比如:自动提交表单.一次提交表单多次submit行为,有的浏览器下点击 ...
- WCF服务显示的是服务器名称而不是IP地址...
打开http://xx.xx.xx.xx:端口号/Service1.svc页面显示的服务地址为: http://xx_yy_server:端口号/Service1.svc?wsdl 是显示的服务器的名 ...
- A funny story in regard to a linux newbie
ZZ from here : ask what kernel ring buffer is A few days ago I started thinking that my linux educa ...
- springMVC 缓存(入门 spring+mybaties+redis一)
使用redis之前需要咋电脑上安装redis: 使用spring+mybaties+redis的本质是扩展类 org.apache.ibatis.cache.Cache:在我们自己扩展的Cache ...
- resin
http://blog.csdn.net/sea0x/article/details/6097531 resin 启动: resin 配置文件摘取: <server-default> &l ...
- ICloud没有密码怎么注销?
忘了密码的用这方法就可以啦1.现在我说你做 . 先进入 iCloud 点击 某某账户(要删的账户)2.第二栏密码那里删除原来的再输入ios(任意密码)3.然后点完成 之后会出现错误.请点 好.然后左上 ...