📄 russia.c
字号:
#include <stdio.h>
#include <time.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <sys/time.h>
#include <signal.h>
/* Define the global parameters */
#define RED 1
#define GREEN 2
#define BLUE 4
#define BRICKXSIZE 9
#define BRICKYSIZE 13
#define BRICKWIDTH 20
#define BRICKHEIGHT 20
static unsigned char gColor=RED;
static GtkWidget *gRedPmap, *gGreenPmap, *gBluePmap;
GtkWidget *window;
static gint g_RBrick[BRICKXSIZE][BRICKYSIZE];
/* global parameters for the brick*/
typedef struct _brickposition {
gint m_x;// based on 0
gint m_y;// based on 0
} BrickPosition;
typedef struct _brickblock {
BrickPosition m_brickpos[4];
BrickPosition m_areastartpos;
BrickPosition m_areaendpos;
} BrickBlock;
typedef struct _candidateblock{
BrickBlock m_brickblock[4];
gint m_index;
}CandidateBlock;
CandidateBlock g_candidateblock[5];
gint g_currentbrickblockindex=0;
gint g_currentbrickx=3;// based on 0
gint g_currentbricky=0;// based on 0
/* end of global parameters */
/* Whether the brick block conflict or not
return 1, OK
return 0, not OK
*/
gint
BrickPositionCorrect(gint m_currentblock,gint m_blockstatus,gint m_startx, gint m_starty){
gint t_loopi, t_tempint,t_indexx,t_indexy,t_brickblockindex, t_tempx, t_tempy;
t_tempint=0;
t_brickblockindex=m_blockstatus;
/* Clear the current exist brick block */
for(t_loopi=0;t_loopi<4;t_loopi++){
gint tt_tempindex;
tt_tempindex=g_candidateblock[g_currentbrickblockindex].m_index;
t_tempx=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_x+g_currentbrickx;
t_tempy=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_y+g_currentbricky;
g_RBrick[t_tempx][t_tempy]=0;
}
/* using the input parameter, judge whether it is possible */
for(t_loopi=0;t_loopi<4;t_loopi++){// for each brick in the brick block
t_indexx=g_candidateblock[m_currentblock].m_brickblock[t_brickblockindex].m_brickpos[t_loopi].m_x;
t_indexy=g_candidateblock[m_currentblock].m_brickblock[t_brickblockindex].m_brickpos[t_loopi].m_y;
t_indexx=t_indexx+m_startx;
t_indexy=t_indexy+m_starty;
/* Get the value from matrix */
if(t_indexx<0||t_indexx>=BRICKXSIZE||t_indexy<0||t_indexy>=BRICKYSIZE) t_tempint++;
else t_tempint=t_tempint+g_RBrick[t_indexx][t_indexy];
}// for each brick in the brick block
/* Recover the current brick */
for(t_loopi=0;t_loopi<4;t_loopi++){
gint tt_tempindex;
tt_tempindex=g_candidateblock[g_currentbrickblockindex].m_index;
t_tempx=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_x+g_currentbrickx;
t_tempy=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_y+g_currentbricky;
g_RBrick[t_tempx][t_tempy]=1;
}
/* return the judgement */
if(t_tempint>=1) return 0;
else return 1;
}
/* Create bitmap */
static GtkWidget*
NewPixmap ( char* filename, GdkWindow *window, GdkColor *background)
{
GtkWidget *wpixmap;
GdkPixmap *pixmap;
GdkBitmap *mask;
pixmap=gdk_pixmap_create_from_xpm(window, &mask, background,
filename);
wpixmap=gtk_pixmap_new(pixmap,mask);
// wpixmap=gtk_image_new_from_file(filename);
return wpixmap;
}
/* Select the desired color*/
static void
SetColor(GtkWidget *widget, gpointer arg)
{
gColor=(unsigned char) arg;
}
void
Update (GtkWidget * widget, char* timestr)
{
time_t timeval;
timeval=time(NULL);
strcpy (timestr, ctime(&timeval));
}
void
PrintAndExit (GtkWidget * widget, char timestr[][26])
{
int i;
for(i=0;i<4;i++)
printf("timestr[%d] is %s", i, timestr[i]);
gtk_main_quit();
}
/* handle for expose the drawing area
*/
static gint
HandleExpose(GtkWidget* widget, GdkEventExpose *event, gpointer arg)
{
/* Calculate the area to be redrawn.
The client area is divided into 9*13 blocks. So it is needed
to calculate the blocks cover the event area. The size of the
client area is 180*260, so 20*20 each block.
*/
gint t_loopx,t_loopy;
GtkPixmap *pixmap;
// GdkBitmap *bitmap;
gint c_xsize=20,c_ysize=20;
gint t_startx, t_starty, t_endx, t_endy;// based on 0
t_startx=event->area.x/c_xsize;
t_starty=event->area.y/c_ysize;
t_endx=(event->area.x+event->area.width-1)/c_xsize;
t_endy=(event->area.y+event->area.height-1)/c_ysize;
/* Select the correct pixmap
*/
switch (gColor){
case RED:
pixmap=GTK_PIXMAP(gRedPmap);
break;
case GREEN:
pixmap=GTK_PIXMAP(gGreenPmap);
break;
case BLUE:
pixmap=GTK_PIXMAP(gBluePmap);
break;
default:
break;
}
/* Redraw the client area
*/
for(t_loopy=t_starty;t_loopy<=t_endy;t_loopy++){// loop y
for(t_loopx=t_startx;t_loopx<=t_endx;t_loopx++){// loop x
// get the value from matrix
if(g_RBrick[t_loopx][t_loopy]==1){// draw one break
gdk_draw_pixmap(widget->window, widget->style->black_gc,
pixmap->pixmap, 0,0,t_loopx*c_xsize,t_loopy*c_ysize,-1,-1);
}else{// end of draw on brick
gdk_window_clear_area (widget->window,t_loopx*c_xsize,t_loopy*c_ysize,c_xsize,c_ysize);// clear the area
}
}// end of loop x
}// end of loop y
}
/* handle for the user input action
*/
static gint
KeyPress(GtkWidget *widget, GdkEventKey *event, gpointer arg)
{
gint t_tempindex,t_tempx,t_tempy,t_retv, t_loopi,tt_loopi;
BrickPosition t_oldstart,t_oldend,t_newstart,t_newend;
GdkEvent t_event;
t_oldstart.m_x=g_currentbrickx;
t_oldstart.m_y=g_currentbricky;
t_tempindex=g_candidateblock[g_currentbrickblockindex].m_index;
t_oldend=g_candidateblock[g_currentbrickblockindex].m_brickblock[t_tempindex].m_areaendpos;
t_oldend.m_x=t_oldend.m_x+g_currentbrickx;
t_oldend.m_y=t_oldend.m_y+g_currentbricky;
t_retv=0;
switch(event->keyval)
{
case GDK_space:
{
t_tempindex=(g_candidateblock[g_currentbrickblockindex].m_index+1)%4;
t_retv=BrickPositionCorrect(g_currentbrickblockindex,t_tempindex,g_currentbrickx, g_currentbricky);
if(t_retv==1){
/* Clear the old value */
for(t_loopi=0;t_loopi<4;t_loopi++){
gint tt_tempindex;
tt_tempindex=g_candidateblock[g_currentbrickblockindex].m_index;
t_tempx=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_x+g_currentbrickx;
t_tempy=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_y+g_currentbricky;
g_RBrick[t_tempx][t_tempy]=0;
}
/* action */
g_candidateblock[g_currentbrickblockindex].m_index=t_tempindex;
/* Set the new value */
for(t_loopi=0;t_loopi<4;t_loopi++){
gint tt_tempindex;
tt_tempindex=g_candidateblock[g_currentbrickblockindex].m_index;
t_tempx=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_x+g_currentbrickx;
t_tempy=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_y+g_currentbricky;
g_RBrick[t_tempx][t_tempy]=1;
}// end of set new value
}// end of brick block changed.
}
break;
case GDK_Down:
{
t_tempindex=g_candidateblock[g_currentbrickblockindex].m_index;
t_retv=BrickPositionCorrect(g_currentbrickblockindex,t_tempindex,g_currentbrickx, g_currentbricky+1);
if(t_retv==1){
/* Clear the old value */
for(t_loopi=0;t_loopi<4;t_loopi++){
gint tt_tempindex;
tt_tempindex=g_candidateblock[g_currentbrickblockindex].m_index;
t_tempx=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_x+g_currentbrickx;
t_tempy=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_y+g_currentbricky;
g_RBrick[t_tempx][t_tempy]=0;
}
/* action */
g_currentbricky++;
/* Set the new value */
for(t_loopi=0;t_loopi<4;t_loopi++){
gint tt_tempindex;
tt_tempindex=g_candidateblock[g_currentbrickblockindex].m_index;
t_tempx=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_x+g_currentbrickx;
t_tempy=g_candidateblock[g_currentbrickblockindex].m_brickblock[tt_tempindex].m_brickpos[t_loopi].m_y+g_currentbricky;
g_RBrick[t_tempx][t_tempy]=1;
}// end of set new value
}// end of brich changed
else{// matrix bottom met. New brick created
t_retv=1;
/* Create a brick block randomly */
g_currentbrickblockindex=g_random_int_range(0,5);
g_currentbrickx=3;
g_currentbricky=0;
g_candidateblock[g_currentbrickblockindex].m_index=g_random_int_range(0,4);
/* Clear the all 1 rows */
gint tt_src=BRICKYSIZE-1;
gint tt_dst=BRICKYSIZE-1;
for(t_loopi=BRICKYSIZE-1;t_loopi>=0;t_loopi--){// adjust g_RBrick
if(tt_src!=tt_dst){// should copy
for( tt_loopi=0;tt_loopi<BRICKXSIZE;tt_loopi++){// copy row
g_RBrick[tt_loopi][tt_dst]=g_RBrick[tt_loopi][tt_src];
}// end of copy row
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -