R语言构造扑克牌自动发牌,洗牌
在R语言构建自动洗牌,发牌
要求:自动洗牌、发牌
任务一:创建一副牌。学会如何使用R的数据类型和数据结构。
任务二:编写发牌和洗牌的函数。学习从一个数据集中抽取想要的数值。
首先需要创建一副牌(不包括大小王),从R语言的数据对象来看,数据框最合适。
因为花色是字符串,而点数是数字,所以能够承担数据类型不同的二维数据对象——数据框最合适。下面是创建pkp数据对象的代码
pkp<-data.frame(face=rep(c(2:10,"J","Q","K","A"),4),hs=rep(c("黑桃","方块","红桃","梅花"),each=13))
然后我们需要构造发牌,洗牌函数
在构造发牌,洗牌函数的过程中,最重要的理解逻辑,怎么才能发牌呢?
不妨思考模拟下日常生活中是怎么发牌的呢?首先我们都是从牌堆里面抽取一张扑克牌,然后牌堆就少了一张牌,继续按照顺序抽取,直到牌堆没有牌。
如果用代码思考的话,就是在pkp这个牌堆里面抽取第一张,然后有pkp[-1,]丢掉这张牌,继续抽取后丢掉,这就是发牌的过程。
#licensing pkp
licensing<-function(){
assign("copypkp",copypkp[-1,],envir = globalenv())
copypkp[1,]
}
在这里需要介绍下assign函数,assign函数是一个赋值语句,与”=”和”<-“不同的是,assign能在不同的环境下赋值。
下面需要介绍环境,环境在R中是比较重要的概念,什么是环境呢?
可以说环境和我们电脑里面的文件夹很类似
环境:用来具体存储对象的地方。
规则1:每一个对象都存储在一个环境当中。
规则2:每一个环境都与一个父环境相连接。构成一个分层的环境系统。
规则3:子环境与父环境的连接是单向的。
parenvs{pryr}:查看R的环境系统,parenvs(all=TRUE)会返回当前会话包含的环境列表。
as.environment():指向环境树中的任意一个环境。
globalenv();base();emptyenv();parent.env()
assign():赋值函数
下面通过parenvs查看当前R语言下的环境
默认环境是globalenv(全局变量),也就是说我们创建对象,一般都是在globalenv环境里,
如果创建函数的话,R会自动给函数分配环境,且函数环境是globalenv的子环境
说环境的话可能不好理解,我们把环境比作文件夹。globalenv环境相当于默认文件夹,我们在globalenv环境创建的对象都储存在默认文件夹里面,函数相当于在默认文件夹里面再创建一个文件夹,函数文件夹创建的对象储存在函数文件夹中。
关于环境有一点很重要。就是如何应用环境里面的对象。下面是环境作用域规则
活动环境:当前R执行活动的地方。
规则1:任何时候,R的活动环境都只有一个。
规则2:所有的新对象都会被存储在该环境中。
environment():查看当前的活动环境。
作用域规则:R搜索对象时会遵循的一系列规则。
规则1:R首先在当前的活动环境中搜索对象。
规则2:在命令行工作中,活动环境就是全局环境。
规则3:当R在某个环境中没有搜索到对象时,R会进入到该环境的父环境。
下面是洗牌函数的构造
我理解的洗牌就是要把pkp这个数据对象里面的顺序打乱,如何打乱顺序呢?
我的思路是,构造一个随机向量,里面有52个值,然后构造一个循环52次的结构,将随机向量一个个的赋值给pkp这个数据对象.下面是洗牌函数代码
#shuffle pkp
shuffle<-function(){
copypkp<-pkp
random<-sample(c(1:52),size=52)
for (i in 1:52)
{
assign("copypkp",copypkp[random,],envir = globalenv())
}
print("your pkp has been shuffled")
}
完整代码如下
#create pkp data
pkp<-data.frame(face=rep(c(2:10,"J","Q","K","A"),4),hs=rep(c("黑桃","方块","红桃","梅花"),each=13))
#copy pkp
copypkp<-pkp
#licensing pkp
licensing<-function(){
assign("copypkp",copypkp[-1,],envir = globalenv())
copypkp[1,]
}
#shuffle pkp
shuffle<-function(){
copypkp<-pkp
random<-sample(c(1:52),size=52)
for (i in 1:52)
{
assign("copypkp",copypkp[random,],envir = globalenv())
}
print("your pkp has been shuffled")
}
有一个点需要特别注意,就是对象的更改。两个函数我都是对copypkp这个数据对象进行更改,pkp这个数据对象是没有变化的。这样有利于shuffle(洗牌)后的重置化。
但是这个自动洗牌,发牌还有一个重大的缺陷:如果pkp这个数据对象不小心被删除的化,整个洗牌,发牌过程都实现不了。
要解决这个问题,我们就必须用到闭包函数的概念和深入理解环境
在下一篇我会详细介绍闭包的实现和环境的深入理解
上一篇: Php图像处理类代码分享_php技巧
下一篇: Hastable 用法及循环读取
推荐阅读