不二如是 发表于 2016-8-26 09:52:58

分享一个基于Qt编写的2048小游戏

#include <cstdio>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <vector>
#include <conio.h>
#include <windows.h>
#include<iostream>

using namespace std;

int table={0},Score=0,Max_number=0;

bool allprint=true;

int&at(int* pn,int x,int y=-1,bool rev=false){
    return rev?(~y?pn:pn):(~y?pn:pn);
}
bool canMove(int* pn,int direction){
    for(int i=0,sum=0;i<4;i++){
      for(int j=0;j<4;j++){
            if(!at(pn,i,j,direction==0))return true;
            if(j&&at(pn,i,j,direction==0)==at(pn,i,j-1,direction==0))return true;
      }
    }
    return false;
}
void gotoxy(int x,int y){
    COORD c; c.X=x;c.Y=y;
    SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE),c);
}
void random_insert(int* pn){
    int dataCount=0;
    for(int i=0;i<16;i++)
      if(pn)
            dataCount++;
    if(dataCount==16)
      return;
    int index=rand()%(16-dataCount);
    int iScan=0;
    while(pn||index--)iScan++;
    pn=(rand()%10)?2:4;
}

int cur_direction(int* pn,int direct,bool visual=false,int* callcount=NULL,int* squareCount=NULL,bool noinsert=false){
    int _score=0,sum=0,square=0,flag=1;
    bool isReverse=direct%2==0;
    for(int iLine=0;iLine<4;iLine++){
      vector<int> line;
      for(int i=(isReverse?0:3);i!=(isReverse?4:-1);i+=(isReverse?1:-1)){
                if(at(pn,iLine,i,direct>1))line.push_back(at(pn,iLine,i,direct>1));
                flag=1;
                while(flag){
                  flag=0;
                  for(int k=1;k<line.size();k++)
                        if(line==line){
                            line[--k]*=2;
                            _score+=line;
                            if(Max_number<line)Max_number=line;
                            line.erase(line.begin()+k+1);
                            flag++;
                        }
                  sum+=flag;
                }
      }
      if(!visual)
            for(int i=(isReverse?0:3);i!=(isReverse?4:-1);i+=(isReverse?1:-1)){
                if(line.empty())at(pn,iLine,i,direct>1)=0;
                else{
                  at(pn,iLine,i,direct>1)=line;
                  line.erase(line.begin());
                }
            }
      for(int i=1;i<line.size();i++)
            if(line*2==line||line==2*line)
                square+=line-line;
    }
    if(callcount)(*callcount)=sum;
    if(squareCount)(*squareCount)=abs(square);
    if((!visual)&&(!noinsert))random_insert(pn);
    return _score;
}
bool isConinue(int *pn=table){
    int dataCount=0;
    for(int i=0;i<16;i++)if(at(pn,i,-1,false))dataCount++;
    return dataCount<16||cur_direction(table,0,true)||cur_direction(table,2,true);
}
void print(){
    if(!allprint)return;
    gotoxy(0,0);
    printf("2048-GameTable designed by X.P.Y\nScore:%d         \n\n\n",Score); //x=1
    for(int i=0;i<16;i++){
      gotoxy((i%4+1)*5+1,(i/4+1)*2+1);
      printf("%d   ",table);
    }
    gotoxy(0,11);
}
int ai_calculate(){
    bool canv=canMove(table,0),canh=canMove(table,1);
    if(!(canv&&canh))return canv?2:0;
    int sum={0},score={0},square={0},ai_table;
    int tmp_sum,tmp_square,index=0,maxScore=-1,curScore=0;
    for(int i=0;i<4;i++){
      for(int k=0;k<4;k++){
            memcpy(ai_table,table,sizeof(int)*16);
            score=cur_direction(ai_table,i,false,sum+i,square+i);
            score+=0.8*cur_direction(ai_table,k,false,&tmp_sum,&tmp_square,true);
            sum+=0.8*tmp_sum;
            square+=0.8*tmp_square;
            for(int j=0;j<4;j++){
                score+=0.4*cur_direction(ai_table,j,true,&tmp_sum,&tmp_square,true);
                sum+=0.4*tmp_sum;
                square+=0.4*tmp_square;
            }
            curScore=2*score+sum;
            if(maxScore<curScore){maxScore=curScore;index=i;}
      }
    }
    return index;
}
void initialize(int n=3){
    memset(table,0,16*sizeof(int));
    Score=Max_number=0;
    while(n--)random_insert(table);
}
void gameJudge(){
    initialize();
    while(isConinue()){
      print();
      switch(getch()){
      case 87:case 119:case 72:Score+=cur_direction(table,0);break;
      case 83:case 115:case 80:Score+=cur_direction(table,1);break;
      case 65:case 97:case 75:Score+=cur_direction(table,2);break;
      case 68:case 100:case 77:Score+=cur_direction(table,3);break;
      }
    }
}
void ai_judge(int nloop=1){
    while(nloop--){
      initialize();
      while(isConinue()){
            Score+=cur_direction(table,ai_calculate());
            print();
      }
      if(allprint)printf("Max Number:%d\n",Max_number);
    }
}
int main(){
    srand(time(0));
    gameJudge();
    return 0;
}

攻城狮和程序猿 发表于 2016-8-26 10:47:32

谢谢楼主分享

不二如是 发表于 2016-8-26 10:52:22

攻城狮和程序猿 发表于 2016-8-26 10:47
谢谢楼主分享

{:10_257:}独乐不如众乐

攻城狮和程序猿 发表于 2016-8-26 10:56:48

不二如是 发表于 2016-8-26 10:52
独乐不如众乐

嘿嘿{:10_256:}

不二如是 发表于 2016-8-26 10:59:36

攻城狮和程序猿 发表于 2016-8-26 10:56
嘿嘿

嘿嘿嘿{:10_297:}
页: [1]
查看完整版本: 分享一个基于Qt编写的2048小游戏