R语言写2048游戏
2048 是一款益智游戏,只需要用方向键让两两相同的数字碰撞就会诞生一个翻倍的数字,初始数字由 2 或者 4 构成,直到游戏界面全部被填满,游戏结束。
编程时并未查看原作者代码,不喜勿喷。
程序结构如下:
R语言代码:
1 #!/usr/bin/Rscript 2 #画背景 3 draw_bg <- function(){ 4 plot(0,0,xlim=c(0,0.8),ylim=c(0,0.8),type='n',xaxs="i", yaxs="i") 5 for (i in c(1:4)){ 6 for (j in c(1:4)){ 7 points(0.1+0.2*(i-1),0.9-0.2*(j),col="gray",pch=15,cex=16)}} 8 } 9 #画数字矩阵 10 draw_num <- function(){ 11 for (i in c(1:4)){ 12 for (j in c(1:4)){ 13 if (e$m[i,j] != 0){ 14 text(0.1+(j-1)*0.2,0.7-(i-1)*0.2,font=2,family="Arial",label=e$m[i,j],cex=2) 15 } 16 } 17 } 18 } 19 #初次运行游戏,生成随机矩阵 20 init <- function(){ 21 e$stage=1 22 mt <- matrix(c(sample(c(2,4),1),rep(0,15)),nrow=4) 23 e$m <- mt[sample(4),sample(4)] 24 draw_bg() 25 draw_num() 26 } 27 28 #移除矩阵数字间的0 29 rm_zero <- function(){ 30 if (e$x==0){ 31 if (e$dir=="up"){ 32 for (c in 1:4) e$m[,c] <- c(e$m[,c][which(e$m[,c]!=0)],rep(0,4-length(e$m[,c][which(e$m[,c]!=0)]))) 33 } 34 if (e$dir=="down"){ 35 for (c in 1:4) e$m[,c] <- c(rep(0,4-length(e$m[,c][which(e$m[,c]!=0)])),e$m[,c][which(e$m[,c]!=0)]) 36 } 37 if (e$dir=="left"){ 38 for (r in 1:4) e$m[r,] <- c(e$m[r,][which(e$m[r,]!=0)],rep(0,4-length(e$m[r,][which(e$m[r,]!=0)]))) 39 } 40 41 if (e$dir=="right"){ 42 for (r in 1:4) e$m[r,] <- c(rep(0,4-length(e$m[r,][which(e$m[r,]!=0)])),e$m[r,][which(e$m[r,]!=0)]) 43 44 } 45 } 46 else{ 47 if (e$dir=="up"){ 48 c <- e$x 49 e$m[,c] <- c(e$m[,c][which(e$m[,c]!=0)],rep(0,4-length(e$m[,c][which(e$m[,c]!=0)]))) 50 } 51 if (e$dir=="down"){ 52 c <- e$x 53 e$m[,c] <- c(rep(0,4-length(e$m[,c][which(e$m[,c]!=0)])),e$m[,c][which(e$m[,c]!=0)]) 54 } 55 if (e$dir=="left"){ 56 r <- e$x 57 e$m[r,] <- c(e$m[r,][which(e$m[r,]!=0)],rep(0,4-length(e$m[r,][which(e$m[r,]!=0)]))) 58 } 59 60 if (e$dir=="right"){ 61 r <- e$x 62 e$m[r,] <- c(rep(0,4-length(e$m[r,][which(e$m[r,]!=0)])),e$m[r,][which(e$m[r,]!=0)]) 63 64 } 65 66 } 67 } 68 69 #在空白处添加随机数字 70 new_mt <- function(){ 71 e$m[sample(which(e$m==0),1)] <- sample(c(2,4),1) 72 } 73 74 #检查是否游戏失败 75 fail <- function(){ 76 if (length(e$m[which(e$m==0)])==0){ 77 e$x=0 78 for (r in 1:3){ 79 for (c in 1:3){ 80 if (e$m[r,c] == e$m[r,c+1] | e$m[r,c] == e$m[r+1,c]){ 81 e$x=1 82 } 83 } 84 } 85 if (e$x==0){ 86 stage2() 87 88 } 89 } 90 } 91 #游戏中 92 stage1 <- function(){ 93 e$stage <- 1 94 e$x <- 0 95 rm_zero() 96 if (e$dir=="left"){ 97 i=1 98 while (i<=4){ 99 if (e$m[i,1] != 0 & e$m[i,1]==e$m[i,2] & e$m[i,1]==e$m[i,3] & e$m[i,1]==e$m[i,4]){ 100 e$m[i,]=rep(c(2*e$m[i,1],0),each=2) 101 e$x=1 102 } 103 else if (e$m[i,2]!=0 & e$m[i,3] != 0 & e$m[i,2]==e$m[i,1] & e$m[i,3]==e$m[i,4]){ 104 e$m[i,]=c(2*e$m[i,1],0,2*e$m[i,3],0) 105 e$x=1 106 } 107 else if (e$m[i,2] != 0 & e$m[i,2]==e$m[i,1]){ 108 e$m[i,]=c(2*e$m[i,1],0,e$m[i,3],e$m[i,4]) 109 e$x=1 110 } 111 else if (e$m[i,3] != 0 & e$m[i,3]==e$m[i,4]){ 112 e$m[i,]=c(e$m[i,1],e$m[i,2],2*e$m[i,3],0) 113 e$x=1 114 } 115 else if (e$m[i,2] != 0 & e$m[i,2]==e$m[i,3]){ 116 e$m[i,]=c(e$m[i,1],2*e$m[i,2],0,e$m[i,4]) 117 e$x=1 118 } 119 i=i+1 120 } 121 rm_zero() 122 new_mt() 123 draw_bg() 124 draw_num() 125 fail() 126 } 127 if (e$dir=="right"){ 128 i=1 129 while (i<=4){ 130 if (e$m[i,1] != 0 & e$m[i,1]==e$m[i,2] & e$m[i,1]==e$m[i,3] & e$m[i,1]==e$m[i,4]){ 131 e$m[i,]=rep(c(0,2*e$m[i,1]),each=2) 132 e$x=1 133 } 134 else if (e$m[i,2] != 0 & e$m[i,3] != 0 & e$m[i,2]==e$m[i,1] & e$m[i,3]==e$m[i,4]){ 135 e$m[i,]=c(0,2*e$m[i,1],0,2*e$m[i,3]) 136 e$x=1 137 } 138 else if (e$m[i,2] != 0 & e$m[i,2]==e$m[i,1]){ 139 e$m[i,]=c(0,2*e$m[i,1],e$m[i,3],e$m[i,4]) 140 e$x=1 141 } 142 else if (e$m[i,3] != 0 & e$m[i,3]==e$m[i,4]){ 143 e$m[i,]=c(e$m[i,1],e$m[i,2],0,2*e$m[i,3]) 144 e$x=1 145 } 146 else if (e$m[i,2] != 0 & e$m[i,2]==e$m[i,3]){ 147 e$m[i,]=c(e$m[i,1],0,2*e$m[i,2],e$m[i,4]) 148 e$x=1 149 } 150 i=i+1 151 } 152 rm_zero() 153 new_mt() 154 draw_bg() 155 draw_num() 156 fail() 157 } 158 159 if (e$dir=="up"){ 160 j=1 161 while (j<=4){ 162 if (e$m[1,j] != 0 & e$m[1,j]==e$m[2,j] & e$m[1,j]==e$m[3,j] & e$m[1,j]==e$m[4,j]){ 163 e$m[,j]=rep(c(2*e$m[1,j],0),each=2) 164 e$x=1 165 } 166 else if (e$m[2,j] != 0 & e$m[3,j] != 0 & e$m[2,j]==e$m[1,j] & e$m[3,j]==e$m[4,j]){ 167 e$m[,j]=c(2*e$m[1,j],0,2*e$m[3,j],0) 168 e$x=1 169 } 170 else if (e$m[2,j] != 0 & e$m[2,j]==e$m[1,j]){ 171 e$m[,j]=c(2*e$m[1,j],0,e$m[3,j],e$m[4,j]) 172 e$x=1 173 } 174 else if (e$m[3,j] != 0 & e$m[3,j]==e$m[4,j]){ 175 e$m[,j]=c(e$m[1,j],e$m[2,j],2*e$m[3,j],0) 176 e$x=1 177 } 178 else if (e$m[2,j] != 0 & e$m[2,j]==e$m[3,j]){ 179 e$m[,j]=c(e$m[1,j],2*e$m[2,j],0,e$m[4,j]) 180 e$x=1 181 } 182 j=j+1 183 } 184 rm_zero() 185 new_mt() 186 draw_bg() 187 draw_num() 188 fail() 189 } 190 if (e$dir=="down"){ 191 j=1 192 while (j<=4){ 193 if (e$m[1,j] != 0 & e$m[1,j]==e$m[2,j] & e$m[1,j]==e$m[3,j] & e$m[1,j]==e$m[4,j]){ 194 e$m[,j]=rep(c(0,2*e$m[1,j]),each=2) 195 e$x=1 196 } 197 else if (e$m[2,j] != 0 & e$m[3,j] != 0 & e$m[2,j]==e$m[1,j] & e$m[3,j]==e$m[4,j]){ 198 e$m[,j]=c(0,2*e$m[1,j],0,2*e$m[3,j]) 199 e$x=1 200 } 201 else if (e$m[2,j] != 0 & e$m[2,j]==e$m[1,j]){ 202 e$m[,j]=c(0,2*e$m[1,j],e$m[3,j],e$m[4,j]) 203 e$x=1 204 } 205 else if (e$m[3,j] != 0 & e$m[3,j]==e$m[4,j]){ 206 e$m[,j]=c(e$m[1,j],e$m[2,j],0,2*e$m[3,j]) 207 e$x=1 208 } 209 else if (e$m[2,j] != 0 & e$m[2,j]==e$m[3,j]){ 210 e$m[,j]=c(e$m[1,j],0,2*e$m[2,j],e$m[4,j]) 211 e$x=1 212 } 213 j=j+1 214 } 215 216 217 rm_zero() 218 new_mt() 219 draw_bg() 220 draw_num() 221 fail() 222 } 223 } 224 stage2<-function(){ 225 e$stage<-2 226 plot(0,0,xlim=c(0,1),ylim=c(0,1),type='n',xaxs="i", yaxs="i") 227 text(0.5,0.7,label="Game Over",cex=2) 228 text(0.5,0.4,label="Space to restart, q to quit.",cex=2,col=4) 229 text(0.2,0.05,label="Author:YwLiao",cex=1) 230 } 231 232 # 开机画图 233 stage0<-function(){ 234 e$stage<-0 235 plot(0,0,xlim=c(0,1),ylim=c(0,1),type='n',xaxs="i", yaxs="i") 236 text(0.5,0.7,label="2048",cex=2) 237 text(0.5,0.4,label="Any keyboard to start",cex=2,col=4) 238 text(0.5,0.3,label="Up,Down,Left,Rigth to control direction",cex=2,col=2) 239 text(0.2,0.05,label="Author:YwLiao",cex=1) 240 } 241 #键盘事件 242 keydown<-function(K){ 243 print(paste("keydown:",K,",stage:",e$stage)); 244 if(e$stage==0){ 245 #开机画面 246 init() 247 return(NULL) 248 } 249 if(e$stage==2){ #结束画面 250 if(K=="q") q() 251 else if(K==' ') stage0() 252 return(NULL) 253 } 254 if(e$stage==1){ #游戏中 255 if(K == "q") { 256 stage2() 257 }else { 258 if(tolower(K) %in% c("up","down","left","right")){ 259 e$dir<-tolower(K) 260 stage1() 261 } 262 } 263 } 264 return(NULL) 265 } 266 267 #开始运行游戏 268 run<-function(){ 269 e<<-new.env() 270 #X11(type="Xlib") #linux系统需添加此行代码,不过字体受到限制,没有windows下大 271 stage0() 272 getGraphicsEvent(prompt="2048",onKeybd=keydown) 273 } 274 275 run()
游戏画面
参考资料
张丹.R的极客理想:http://www.kuqin.com/shuoit/20140704/340987.html