游戏规则:
在10X10的棋盘上有五种颜色的棋子。
点击一个棋子,再点击一个空格子,如果两者之间有一条路径的话,棋子会移动到空格子内。
每移动一次,棋盘上会增加三个棋子,其位置和颜色都是随机的。
当横向、竖向或斜向有五个或以上棋子有相同颜色时,这些棋子会消去。
当棋盘上没有空格子时,游戏结束。
得分为消去得棋子的个数。
程序效果:
代码:
main.cpp
//main.cpp
1 #if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif #include <tchar.h>
#include <windows.h>
#include "matrix.h"
#include "matrix.cpp"
#include <stdio.h>
#include <pthread.h>
#define BKCOLOR RGB(200,200,200)
int score=;
int WIDTH=;
int HEIGHT=;
Matrix ma;
int width=;//WIDTH/ma.getN();
int height=;//HEIGHT/ma.getN();
PAINTSTRUCT ps ;
static HBRUSH red_brush =CreateSolidBrush (RGB(,,));
static HBRUSH green_brush =CreateSolidBrush (RGB(,,));
static HBRUSH blue_brush =CreateSolidBrush (RGB(,,));
static HBRUSH yellow_brush =CreateSolidBrush (RGB(,,));
static HBRUSH purple_brush =CreateSolidBrush (RGB(,,));
static HBRUSH white_brush =CreateSolidBrush (BKCOLOR);
Point * s_lattice=new Point(,),*d_lattice=new Point(,);
bool paint_path=false;
int path_color=;
Point* sou=new Point();
Point* dest=new Point();
Point* mouse=new Point(,);
Point *position=new Point(,);
Link<Point *>* path;
HBRUSH hBrush ;
HDC hdc;
POINT pc;
RECT client_rect;
int score_height; /* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */
TCHAR szClassName[ ] = _T("Game"); int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow) {
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = ; /* No extra bytes after the window class */
wincl.cbWndExtra = ; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return ; /* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("GLine"), /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
WIDTH, /* The programs width */
HEIGHT, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
); /* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow); /* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, , )) {
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
} /* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
int select_brush(int color,HDC hdc) {
switch(color) {
case RED:
SelectObject (hdc, red_brush);
break;
case GREEN:
SelectObject (hdc, green_brush);
break;
case BLUE:
SelectObject (hdc, blue_brush);
break;
case YELLOW:
SelectObject (hdc, yellow_brush);
break;
case PURPLE:
SelectObject (hdc, purple_brush);
break;
default:
SelectObject (hdc, white_brush);
}
return color;
}
void paint_lattice(Point * p,HDC hdc,int color) { //-1 original color
int left=p->y*width;
int right=(p->y+)*width;
int top=p->x*height+score_height;
int bottom=(p->x+)*height+score_height;
MoveToEx (hdc,left,top, NULL) ;
LineTo (hdc,right,top) ;
MoveToEx (hdc,left,top, NULL) ;
LineTo (hdc,left,bottom) ;
MoveToEx (hdc,right,top, NULL) ;
LineTo (hdc,right,bottom) ;
MoveToEx (hdc,left,bottom, NULL) ;
LineTo (hdc,right,bottom) ;
int paint_color;
if(color!=-) {
paint_color=select_brush(color,hdc);
} else {
paint_color=select_brush(ma.get_color(p),hdc);
}
if(paint_color!=BLANK)Ellipse (hdc,left+,top+,right-,bottom-) ;
}
void mouse_to_position() {
position->x=(mouse->y-score_height)/height;
position->y=mouse->x/width;
}
char *get_score_string(char* content){
char *message=new char[];
sprintf (message, "%s %d .",content,score);
return message;
}
int show_score(HWND hwnd,char* content,char* title) {
MessageBox(hwnd,get_score_string(content),title,NULL);
}
void after_show_path(HWND hwnd) {
ma.set_flag(dest,ma.get_color(sou));
ma.set_blank(sou);
ma.random_set();
ma.eliminate(score);
InvalidateRect (hwnd,NULL, true) ;
if(ma.is_all_not_blank()) {
show_score(hwnd,"GAME OVER.Your score is","你输了");
}
}
struct args {
HWND hwnd;
HDC hdc;
};
void* show_path(void* ar) {
path=new Link<Point *>();
ma.get_path(sou,dest,path);
struct args* arg=(struct args*) ar;
HWND hwnd=arg->hwnd;
HDC hdc=arg->hdc;
if(path->get_first()==NULL) {
return ;
}
//path->show_link();
path->seek_to_first();
Point* node=path->get_first();
path_color=ma.get_color(node);
s_lattice=node;
paint_path=true;
while((node=path->get_next())!=NULL) {
d_lattice=node;
InvalidateRect (hwnd,NULL, true) ;
Sleep();
}
paint_path=false;
after_show_path(hwnd);
} void init_GUI(HWND hwnd,HDC hdc) {
SetBkColor(hdc,BKCOLOR);
for(int i=; i<ma.getN(); i++) {
for(int j=; j<ma.getN(); j++) {
Point* p=new Point(i,j);
paint_lattice(p,hdc,-);
delete p;
}
}
char * score=get_score_string("You Score: ");
TextOut(hdc,,score_height/,score,strlen(score));
} void sou_dest(HWND hwnd,HDC hdc) {
static pthread_t show_path_pth;
static int ret;
mouse_to_position();
if(sou!=NULL) {
if(ma.get_color(position)==BLANK) {
*dest=*position;
struct args arg;
arg.hdc=hdc;
arg.hwnd=hwnd;
ret= pthread_create( &show_path_pth, NULL, &show_path, &arg ); //参数:创建的线程id,线程参数,线程运行函数的起始地址,运行函数的参数
if( ret != ) { //创建线程成功返回0
printf("pthread_create error:error_code=%d\n",ret );
}
} else {
*sou=*position;
}
} else {
if(ma.get_color(position)!=BLANK) {
*sou=*position;
}
}
}
/* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) { /* handle the messages */
case WM_CREATE: {
ma.init();
GetClientRect (hwnd, &client_rect) ;
WIDTH=client_rect.right-client_rect.left ;
HEIGHT=client_rect.bottom-client_rect.top ;
score_height=HEIGHT/;
width=WIDTH/ma.getN();
height=(HEIGHT-score_height)/ma.getN();
InvalidateRect (hwnd,NULL, true) ;
}
break;
case WM_DESTROY:
PostQuitMessage (); /* send a WM_QUIT to the message queue */
break;
case WM_LBUTTONUP: {
GetCursorPos(&pc);
ScreenToClient(hwnd,&pc);
mouse->x=pc.x;
mouse->y=pc.y;
sou_dest(hwnd,hdc);
}
break;
case WM_RBUTTONUP: {
show_score(hwnd,"","得分");
}
break;
case WM_PAINT: {
hdc = BeginPaint (hwnd, &ps) ;
init_GUI(hwnd,hdc);
if(paint_path) {
paint_lattice(s_lattice,hdc,BLANK);
paint_lattice(d_lattice,hdc,path_color);
}
EndPaint (hwnd, &ps) ;
}
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return ;
}
matrix.h
//matrix.h
1 #ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED
#pragma once #define BLANK 0
#define RED 1
#define GREEN 2
#define BLUE 3
#define YELLOW 4
#define PURPLE 5 class Point {
private : public:
int x;
int y;
Point(int xx,int yy);
Point();
bool operator ==(Point p);
Point& operator =(Point p);
void show();
};
class node {
public :
int x;
int y;
node* father;
node();
node(int xx,int yy,node* f);
};
template<class T>
class LinkNode {
private: public:
T po;
LinkNode* next;
LinkNode(T pp);
LinkNode& operator=(LinkNode nn);
void show_node();
};
template <class T>
class Link {
private:
LinkNode<T>* head=NULL;
LinkNode<T>* p=NULL;
LinkNode<T>* tail=NULL;
public:
friend class Matrix;
void seek_to_first();
T get_first();
T remove_first();
T get_next();
void add_to_first(T t);
void add_to_last(T t);
void show_link();
};
class Matrix {
private:
int N=;
int COLOR_NUM=;
int** matrix;
int max_random_set_num=;
int get_random_num(int x);
void print_matrix() ;
bool random_set_one() ;
bool is_out(int x,int y) ;
public:
int getN() ;
Matrix() ;
void init();
void set_flag(Point* p,int color) ;
void set_blank(Point* p);
bool is_in_que(int** in,int x,int y) ;
void get_path(Point *s,Point* dest,Link<Point *> *&l) ;
void random_set(int n) ;
int get_color(Point *p) ;
int get_color(int x,int y);
int sget_color(int dir,int x,int y,int n,int color);
void test_line(int x,int y,int dir,int &score);
int eliminate(int & score) ;
bool is_all_not_blank();
};
#endif // MATRIX_H_INCLUDED
matrix.cpp
//matrix.cpp
1 #include "matrix.h" #include <stdlib.h>
#include <time.h>
#include <stdio.h> Point::Point(int xx,int yy) {
x=xx;
y=yy;
}
Point::Point() {}
bool Point::operator ==(Point p) {
return x==p.x&y==p.y;
}
Point& Point::operator =(Point p) {
x=p.x;
y=p.y;
}
void Point::show() {
printf("(%d,%d)->",x,y);
} node::node() {}
node::node(int xx,int yy,node* f) {
x=xx;
y=yy;
father=f;
} template<class T>
LinkNode<T>::LinkNode(T pp) {
po=pp;
next=NULL;
}
template<class T>
LinkNode<T>& LinkNode<T>::operator=(LinkNode<T> nn) {
po=nn.p;
next=nn.next;
}
template<class T>
void LinkNode<T>::show_node() {
po->show();
} template<class T>
void Link<T>::seek_to_first() {
p=head;
}
template<class T>
T Link<T>::get_first() {
return head==NULL?NULL:head->po;
}
template<class T>
T Link<T>::remove_first() {
if(head==NULL)return NULL;
T *temp=&(head->po);
head=head->next;
return *temp;
}
template<class T>
T Link<T>::get_next() {
if(p==tail)return NULL;
if(p==NULL)return NULL;
if(p->next==NULL)return NULL;
p=p->next;
return p->po;
}
template<class T>
void Link<T>::add_to_first(T t) {
LinkNode<T>* x=new LinkNode<T>(t);
x->next=head;
head=x;
if(tail=NULL) {
tail=head;
return ;
}
}
template<class T>
void Link<T>::add_to_last(T t) {
LinkNode<T>* x=new LinkNode<T>(t);
if(head==NULL) {
head=x;
x->next=NULL;
tail=x;
return ;
}
tail->next=x;
x->next=NULL;
tail=x;
}
template<class T>
void Link<T>::show_link() {
printf("show_link:\n");
p=head;
while(p!=NULL) {
p->show_node();
p=p->next;
}
printf("\n");
} int Matrix::get_random_num(int x) {
int n=rand()%x;
return n;
}
void Matrix::print_matrix() {
printf("matrix:\n");
for(int i=; i<N; i++) {
for(int j=; j<N; j++) {
printf("%d",matrix[i][j]);
}
printf("\n");
}
} bool Matrix::random_set_one() {
int x=get_random_num(N),y=get_random_num(N);
if(matrix[x][y]!=BLANK) {
return false;
}
Point *p=new Point(x,y);
set_flag(p,get_random_num(COLOR_NUM)+);
return true;
}
bool Matrix::is_out(int x,int y) {
return x<|x>=N|y<|y>=N;
} int Matrix::getN() {
return N;
}
Matrix::Matrix() {
matrix=new int*[N];
for(int i=; i<N; i++) {
matrix[i]=new int[N];
for(int j=; j<N; j++) {
matrix[i][j]=BLANK;
}
}
srand(time());
} void Matrix::init() {
random_set(N*N/);
//print_matrix();
}
void Matrix::set_flag(Point* p,int color) {
matrix[p->x][p->y]=color;
}
void Matrix::set_blank(Point* p) {
matrix[p->x][p->y]=BLANK;
} bool Matrix::is_in_que(int** in,int x,int y) {
return false;
} void Matrix::get_path(Point *s,Point* dest,Link<Point *> *&l) {
if(!(get_color(s)!=BLANK&&get_color(dest)==BLANK))return ;
static int xc[]= {-,,,};
static int yc[]= {,,-,};
int xt,yt;
Link<node*> que;
node* temp=new node(s->x,s->y,NULL);
que.add_to_last(temp);
node* dest_node;
bool flag=true;
bool** in=new bool*[N];
for(int i=; i<N; i++) {
in[i]=new bool[N];
for(int j=; j<N; j++) {
in[i][j]=false;
}
}
in[temp->x][temp->y]=true;
while(flag&&que.get_first()!=NULL) {
temp=que.remove_first();
if(temp==NULL) {
break;
}
for(int i=; i<; i++) {
xt=temp->x+xc[i];
yt=temp->y+yc[i];
if((!is_out(xt,yt))&&(!in[xt][yt])) {
node* new_node=new node(xt,yt,temp);
if(xt==dest->x&&yt==dest->y) {
dest_node=new_node;
flag=false;
break;
}
if(get_color(xt,yt)==BLANK) {
in[xt][yt]=true;
que.add_to_last(new_node);
}
}
}
}
if(flag) {
return ;
}
node *n=dest_node;
while(n!=NULL) {
Point *lp=new Point(n->x,n->y);
l->add_to_first(lp);
n=n->father;
}
}
void Matrix::random_set(int n) {
int i=;
srand(time());
int try_time=;
while(i<n&&try_time<N*N*N) {
try_time++;
if(random_set_one()) {
i++;
}
}
return ;
}
int Matrix::get_color(Point *p) {
return matrix[p->x][p->y];
}
int Matrix::get_color(int x,int y) {
return matrix[x][y];
}
int Matrix::sget_color(int dir,int x,int y,int n,int color) {
switch(dir) {
case :
y+=n;
break;
case :
x+=n;
y+=n;
break;
case :
x+=n;
break;
case :
x+=n;
y-=n;
}
if(is_out(x,y)) {
return -;
}
if(color!=-) {
matrix[x][y]=color;
return -;
}
return get_color(x,y);
}
void Matrix::test_line(int x,int y,int dir,int &score) {
int color=get_color(x,y);
if(color==BLANK)return ;
for(int k=; k<; k++) {
if(sget_color(dir,x,y,k,-)!=color) {
return ;
}
}
int k=;
for( ;; k++) {
if(sget_color(dir,x,y,k,-)!=color)break;
sget_color(dir,x,y,k,BLANK);
}
score+=k;
}
int Matrix::eliminate(int & score) {
for(int i=; i<N; i++) {
for(int j=; j<N; j++) {
for(int k=; k<; k++) {
test_line(i,j,k,score);
}
}
}
}
bool Matrix::is_all_not_blank() {
for(int i=; i<N; i++) {
for(int j=; j<N; j++) {
if(matrix[i][j]==BLANK) {
return false;
}
}
}
return true;
}
旧函数:
// int tree(node * n,node* father,Point* dest,node * temp)
// {
// static int xc[4]= {-1,1,0,0};
// static int yc[4]= {0,0,-1,1};
// if(n==NULL)
// {
// return -1;
// }
// printf("n:(%d,%d) ",n->x,n->y);
// n->father=father;
// int xt,yt;
// Link<Point *> nei;
// printf("neis: ");
// for(int i=0; i<4; i++)
// {
// xt=n->x+xc[i];
// yt=n->y+yc[i];
// if((!is_out(xt,yt))&&nn[xt][yt].father==NULL&&nn[xt][yt].father==temp)
// {
//
// if(xt==dest->x&&yt==dest->y)
// {
// printf("(%d,%d) ",xt,yt);
// nn[xt][yt].father=n;
// return 0;
// }
// if(get_color(xt,yt)==BLANK)
// {
// printf("(%d,%d) ",xt,yt);
// Point *ptemp=new Point(xt,yt);
// nei.add_to_first(ptemp);
// nn[xt][yt].father=n;
// }
// }
// }
// printf("\n");
// nei.seek_to_first();
// Point *pp;
// if((pp=nei.get_first())!=NULL){
// if(tree(&nn[pp->x][pp->y],n,dest,temp)==0)return 0;
// }
// while((pp=nei.get_next())!=NULL){
// if(tree(&nn[pp->x][pp->y],n,dest,temp)==0)return 0;
// }
// return 1;
// } // void get_path(Point *s,Point* dest,Link<Point *> *&l)
// {
// printf("1\n");
// node* temp=new node;
// tree(&nn[s->x][s->y],temp,dest,temp);
// printf("\n\nfathers:\n");
//
// for(int i=0; i<N; i++)
// {
// for(int j=0; j<N; j++)
// {
// if(nn[i][j].father!=NULL){
// printf("(%d",nn[i][j].x);
// printf(",%d)",nn[i][j].y);
// printf("->(%d",nn[i][j].father->x);
// printf(",%d)\n",nn[i][j].father->y);
// }
// }
// printf("\n");
// }
//
// node* n=&nn[dest->x][dest->y];
//
// while(n!=temp)
// {
// Point *lp=new Point(n->x,n->y);
// l->add_to_first(lp);
// n=n->father;
// }
// printf("3\n");
// }
程序写于大三下学期,2016年3月。
2016.4.12更新博客。