R语言写2048游戏
2048 是一款益智游戏,只需要用方向键让两两相同的数字碰撞就会诞生一个翻倍的数字,初始数字由 2 或者 4 构成,直到游戏界面全部被填满,游戏结束。
编程时并未查看原作者代码,不喜勿喷。
程序结构如下:

R语言代码:
#!/usr/bin/Rscript
#画背景
draw_bg <- function(){
plot(0,0,xlim=c(0,0.8),ylim=c(0,0.8),type='n',xaxs="i", yaxs="i")
for (i in c(1:4)){
for (j in c(1:4)){
points(0.1+0.2*(i-1),0.9-0.2*(j),col="gray",pch=15,cex=16)}}
}
#画数字矩阵
draw_num <- function(){
for (i in c(1:4)){
for (j in c(1:4)){
if (e$m[i,j] != 0){
text(0.1+(j-1)*0.2,0.7-(i-1)*0.2,font=2,family="Arial",label=e$m[i,j],cex=2)
}
}
}
}
#初次运行游戏,生成随机矩阵
init <- function(){
e$stage=1
mt <- matrix(c(sample(c(2,4),1),rep(0,15)),nrow=4)
e$m <- mt[sample(4),sample(4)]
draw_bg()
draw_num()
} #移除矩阵数字间的0
rm_zero <- function(){
if (e$x==0){
if (e$dir=="up"){
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)])))
}
if (e$dir=="down"){
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)])
}
if (e$dir=="left"){
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)])))
} if (e$dir=="right"){
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)]) }
}
else{
if (e$dir=="up"){
c <- e$x
e$m[,c] <- c(e$m[,c][which(e$m[,c]!=0)],rep(0,4-length(e$m[,c][which(e$m[,c]!=0)])))
}
if (e$dir=="down"){
c <- e$x
e$m[,c] <- c(rep(0,4-length(e$m[,c][which(e$m[,c]!=0)])),e$m[,c][which(e$m[,c]!=0)])
}
if (e$dir=="left"){
r <- e$x
e$m[r,] <- c(e$m[r,][which(e$m[r,]!=0)],rep(0,4-length(e$m[r,][which(e$m[r,]!=0)])))
} if (e$dir=="right"){
r <- e$x
e$m[r,] <- c(rep(0,4-length(e$m[r,][which(e$m[r,]!=0)])),e$m[r,][which(e$m[r,]!=0)]) } }
} #在空白处添加随机数字
new_mt <- function(){
e$m[sample(which(e$m==0),1)] <- sample(c(2,4),1)
} #检查是否游戏失败
fail <- function(){
if (length(e$m[which(e$m==0)])==0){
e$x=0
for (r in 1:3){
for (c in 1:3){
if (e$m[r,c] == e$m[r,c+1] | e$m[r,c] == e$m[r+1,c]){
e$x=1
}
}
}
if (e$x==0){
stage2() }
}
}
#游戏中
stage1 <- function(){
e$stage <- 1
e$x <- 0
rm_zero()
if (e$dir=="left"){
i=1
while (i<=4){
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]){
e$m[i,]=rep(c(2*e$m[i,1],0),each=2)
e$x=1
}
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]){
e$m[i,]=c(2*e$m[i,1],0,2*e$m[i,3],0)
e$x=1
}
else if (e$m[i,2] != 0 & e$m[i,2]==e$m[i,1]){
e$m[i,]=c(2*e$m[i,1],0,e$m[i,3],e$m[i,4])
e$x=1
}
else if (e$m[i,3] != 0 & e$m[i,3]==e$m[i,4]){
e$m[i,]=c(e$m[i,1],e$m[i,2],2*e$m[i,3],0)
e$x=1
}
else if (e$m[i,2] != 0 & e$m[i,2]==e$m[i,3]){
e$m[i,]=c(e$m[i,1],2*e$m[i,2],0,e$m[i,4])
e$x=1
}
i=i+1
}
rm_zero()
new_mt()
draw_bg()
draw_num()
fail()
}
if (e$dir=="right"){
i=1
while (i<=4){
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]){
e$m[i,]=rep(c(0,2*e$m[i,1]),each=2)
e$x=1
}
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]){
e$m[i,]=c(0,2*e$m[i,1],0,2*e$m[i,3])
e$x=1
}
else if (e$m[i,2] != 0 & e$m[i,2]==e$m[i,1]){
e$m[i,]=c(0,2*e$m[i,1],e$m[i,3],e$m[i,4])
e$x=1
}
else if (e$m[i,3] != 0 & e$m[i,3]==e$m[i,4]){
e$m[i,]=c(e$m[i,1],e$m[i,2],0,2*e$m[i,3])
e$x=1
}
else if (e$m[i,2] != 0 & e$m[i,2]==e$m[i,3]){
e$m[i,]=c(e$m[i,1],0,2*e$m[i,2],e$m[i,4])
e$x=1
}
i=i+1
}
rm_zero()
new_mt()
draw_bg()
draw_num()
fail()
} if (e$dir=="up"){
j=1
while (j<=4){
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]){
e$m[,j]=rep(c(2*e$m[1,j],0),each=2)
e$x=1
}
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]){
e$m[,j]=c(2*e$m[1,j],0,2*e$m[3,j],0)
e$x=1
}
else if (e$m[2,j] != 0 & e$m[2,j]==e$m[1,j]){
e$m[,j]=c(2*e$m[1,j],0,e$m[3,j],e$m[4,j])
e$x=1
}
else if (e$m[3,j] != 0 & e$m[3,j]==e$m[4,j]){
e$m[,j]=c(e$m[1,j],e$m[2,j],2*e$m[3,j],0)
e$x=1
}
else if (e$m[2,j] != 0 & e$m[2,j]==e$m[3,j]){
e$m[,j]=c(e$m[1,j],2*e$m[2,j],0,e$m[4,j])
e$x=1
}
j=j+1
}
rm_zero()
new_mt()
draw_bg()
draw_num()
fail()
}
if (e$dir=="down"){
j=1
while (j<=4){
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]){
e$m[,j]=rep(c(0,2*e$m[1,j]),each=2)
e$x=1
}
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]){
e$m[,j]=c(0,2*e$m[1,j],0,2*e$m[3,j])
e$x=1
}
else if (e$m[2,j] != 0 & e$m[2,j]==e$m[1,j]){
e$m[,j]=c(0,2*e$m[1,j],e$m[3,j],e$m[4,j])
e$x=1
}
else if (e$m[3,j] != 0 & e$m[3,j]==e$m[4,j]){
e$m[,j]=c(e$m[1,j],e$m[2,j],0,2*e$m[3,j])
e$x=1
}
else if (e$m[2,j] != 0 & e$m[2,j]==e$m[3,j]){
e$m[,j]=c(e$m[1,j],0,2*e$m[2,j],e$m[4,j])
e$x=1
}
j=j+1
} rm_zero()
new_mt()
draw_bg()
draw_num()
fail()
}
}
stage2<-function(){
e$stage<-2
plot(0,0,xlim=c(0,1),ylim=c(0,1),type='n',xaxs="i", yaxs="i")
text(0.5,0.7,label="Game Over",cex=2)
text(0.5,0.4,label="Space to restart, q to quit.",cex=2,col=4)
text(0.2,0.05,label="Author:YwLiao",cex=1)
} # 开机画图
stage0<-function(){
e$stage<-0
plot(0,0,xlim=c(0,1),ylim=c(0,1),type='n',xaxs="i", yaxs="i")
text(0.5,0.7,label="",cex=2)
text(0.5,0.4,label="Any keyboard to start",cex=2,col=4)
text(0.5,0.3,label="Up,Down,Left,Rigth to control direction",cex=2,col=2)
text(0.2,0.05,label="Author:YwLiao",cex=1)
}
#键盘事件
keydown<-function(K){
print(paste("keydown:",K,",stage:",e$stage));
if(e$stage==0){
#开机画面
init()
return(NULL)
}
if(e$stage==2){ #结束画面
if(K=="q") q()
else if(K==' ') stage0()
return(NULL)
}
if(e$stage==1){ #游戏中
if(K == "q") {
stage2()
}else {
if(tolower(K) %in% c("up","down","left","right")){
e$dir<-tolower(K)
stage1()
}
}
}
return(NULL)
} #开始运行游戏
run<-function(){
e<<-new.env()
#X11(type="Xlib") #linux系统需添加此行代码,不过字体受到限制,没有windows下大
stage0()
getGraphicsEvent(prompt="",onKeybd=keydown)
} run()
游戏画面

参考资料
张丹.R的极客理想:http://www.kuqin.com/shuoit/20140704/340987.html
R语言写2048游戏的更多相关文章
- C语言写猜拳游戏中遇到的函数循环小问题
各位可能在初学C语言的时候都有写过猜拳游戏.但在写猜拳的函数时,避免不了会使用循环. 当函数被套在一个循环中的时候,你的计分变量可能就会被重置为函数体里的初始值.那么怎么解决这个问题? 其实很简单,你 ...
- js写2048游戏代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- R语言写简单线性回归
library(MASS) library(ISLR) lm.fit <- lm(medv~lstat,data=Boston) attach(Boston) lm.fit = lm(medv~ ...
- R语言中函数调试
有时候会用R语言写一下简单的脚本处理函数,加入需要调试的话可以按照下面的步骤进行: fun <- function(x , y){ x + y x - y x * y x / y } debug ...
- 决策树ID3原理及R语言python代码实现(西瓜书)
决策树ID3原理及R语言python代码实现(西瓜书) 摘要: 决策树是机器学习中一种非常常见的分类与回归方法,可以认为是if-else结构的规则.分类决策树是由节点和有向边组成的树形结构,节点表示特 ...
- C语言写的2048小游戏
基于"基于C_语言的2048算法设计_颜冠鹏.pdf" 这一篇文献提供的思路 在中国知网上能找到 就不贴具体内容了 [摘 要] 针对2048的游戏规则,分析了该游戏的算法特点,对其 ...
- 一个用 C 语言写的迷你版 2048 游戏,仅仅有 500个字符
Jay Chan 用 C 语言写的一个迷你版 2048 游戏,仅仅有 487 个字符. 来围观吧 M[16],X=16,W,k;main(){T(system("stty cbreak&qu ...
- C++学习(三十九)(C语言部分)之 游戏项目(2048游戏)
/***************************项目 2048**********************c语言编写 图形库制作时间:2019.04.03 准备工具: vs2013 图形库 i ...
- C语言实现2048小游戏
目录 2048 一.设计思路 1.游戏规则 2.思路 二.代码实现 1.存储结构 2.初始化游戏数据 3.向左合并 4.其他方向合并 5.产生新的方块 6.源代码 7.实例演示 三.问题 2048 一 ...
随机推荐
- table标签中thead、tbody、tfoot的作用
为了让大表格(table)在下载的时候可以分段的显示,就是说在浏览器解析HTML时,table是作为一个整体解释的,使用tbody可以优化显示.如果表格很长,用tbody分段,可以一部分一部分地显示, ...
- JavaScript 图片轮播入门
轮播要求:一个在页面居中的矩形框,图片依次从矩形框中经过 当图片完整占满矩形框时 停留一小段时间再向左边移动经过矩形框的图片自动跑到右边最后一个图的后面.核心原理:在一个for循环中利用offsetl ...
- wemall app商城源码中基于JAVA的绑定和处理fragments和viewpager之间的逻辑关系代码
wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...
- 你可记得曾经的-------- C#面向对象的“基础”
1.C#中构造函数定义的理解: ①构造函数名与所在的类名相同 ②构造函数可以重载 ③构造函数可以带参数 ④构造函数没有返回值,且不允许写出void,可以有参也可以无参 ...
- Office 365 开发概览系列文章和教程
Office 365 开发概览系列文章和教程 原文于2017年2月26日首发于LinkedIn,请参考链接 引子 之前我在Office 365技术社群(O萌)中跟大家提到,3月初适逢Visual St ...
- Python中的变量
多个变量赋值 Python允许你同时为多个变量赋值.例如: a = b = c = 1 以上实例,创建一个整型对象,值为1,三个变量被分配到相同的内存空间上. 您也可以为多个对象指定多个变量.例如: ...
- oracle配置监听图形界面不出来解决方法
ROOT用户下,执行 xhost + 然后再切换到oracle用户运行netca DISPLAY 在Linux/Unix类操作系统上, DISPLAY用来设置将图形显示到何处. 直接登陆图形界面或 ...
- 用SSE指令计算点乘和累加
void sse_mul_float:两段内存float数据点乘,结果覆盖第一组内存. float sse_acc_float:一组内存float值累加. 注: 1. 没有考虑中间的精确问题,结果会有 ...
- Angular2开发拙见——组件规划篇
本文集中讲讲笔者目前使用ng2来开发项目时对其组件的使用的个人的一些拙劣的经验. 先简单讲讲从ng1到ng2框架下组件的职责与地位: ng1中的一大特色--指令,分为属性型.标签型.css类型和注释型 ...
- Oracle存储过程的调用和执行
1.什么是存储过程: 用于在数据库中完成特定的操作或者任务.是一个PLSQL程序块,可以永久的保存在数据库中以供其他程序调用. 2.无参存储过程的使用: Normal 0 7.8 磅 0 2 fals ...