swift--广东麻将简化版
接上篇,本人之前使用一直做微信小程序,现初学SWIFT,主要通过这种小游戏练下手,不正之处请高手指定,不胜感谢。本人V信号:948943912。
// 广东麻将简化版
//
// Created by terry on 2018/8/21.
// 功能:
// 1.在控制台操作。麻将有东西南北中发白,用2颗骰子。
// 2. 创建一幅麻将并洗牌,丢骰子后根据点数发牌,并显示每个玩家的牌面。按点数确定谁是庄家,
// 3.发牌后,对每人的牌面进行排序并显示出来
// 3.可以碰,杠,不能吃牌;没有癞子。只能自摸。胡牌后显示结果(但由于是控制台,此项省略,后续再补上。)
// 4. IOS10.13+xcode8编译通过
// 5.运行效果:
开始创建玩家。。。
创建 4 个玩家,玩家创建结束。。。。
创建麻将成功。。。。
第1次洗牌。。。
第2次洗牌。。。
第3次洗牌。。。
第4次洗牌。。。
第5次洗牌。。。
第6次洗牌。。。
第7次洗牌。。。
第8次洗牌。。。
第9次洗牌。。。
第10次洗牌。。。
洗牌结束。。。
2个骰子分别是:2:4,结果是6
庄家是2…
1号玩家牌面是:
[7万]、[7万]、[8万]、[8万]、[8条]、[9条]、[2筒]、[3筒]、[5筒]、[6筒]、[8筒]、[南]、[北]、
2号玩家牌面是:
[1万]、[3万]、[5万]、[8万]、[2条]、[9条]、[1筒]、[1筒]、[1筒]、[7筒]、[东]、[东]、[北]、[中]、
3号玩家牌面是:
[1万]、[3万]、[4万]、[4万]、[7万]、[8万]、[5条]、[3筒]、[4筒]、[5筒]、[9筒]、[发]、[白]、
4号玩家牌面是:
[5万]、[9万]、[4条]、[4条]、[6条]、[7条]、[7条]、[东]、[西]、[中]、[中]、[发]、[白]、
Program ended with exit code: 0
设计思路:
// 1.设置4个玩家,位置定义:自己是1,左边是2,对面是3,右边是4
创建以下类:
MaJiang : 麻将父类;
MaJiangNumber : 数字牌类,继承自麻将父类。
MaJiangWind : 风牌类,继承自麻将父类。
MaJiangFactory : 麻将工厂类,用于生成麻将
MaJiangType : 枚举类型,设定麻将10种牌型
Tools : 工具类,专门用来进行计算
Player : 描述玩家;
Game:控制游戏流程
每个方法 和属性都有详细注释
import Foundation
/// 玩家类
class Player{
var id:Int = 0 //ID
var name:String = “” //姓名
var playerMaJiangs:[MaJiang]=[] //玩家手上的牌
var fullNmae:String { //玩家的完整信息
return String(id)+”号玩家:”+name
}
init(id:Int,name:String) {
self.id=id
self.name=name
}
}
/// 麻将的类型
///
/// - Wan: 万
/// - Tiao: 条
/// - Tong: 筒
/// - Dong: 东风
/// - Nan: 南风
/// - Xi: 西风
/// - Bei: 北分
/// - HongZhong: 红中
/// - FaCai: 发财
/// - BaiBan: 白板
enum MaJiangType:Int{
case Wan=1
case Tiao=2
case Tong=3
case Dong=4
case Nan=5
case Xi=6
case Bei=7
case HongZhong=8
case FaCai=9
case BaiBan=10
}
/// 根据座位图确定编号,自己是1
///
/// - zuo: 左边是2
/// - DuiMian: 对面是3
/// - You: 右边是4
enum ZuoWei:Int{
case zuo=2
case DuiMian=3
case You=4
}
/// 麻将的父类
class MaJiang {
var type:MaJiangType
/// 得到麻将的类型
///
/// - Returns: 返回麻将的类型--枚举值
func getType() -> MaJiangType {
return type
}
init(type:MaJiangType) {
self.type=type
}
func toString() -> String {
return "[" + String(type.rawValue) + "]"
}
}
/// 数字麻将类=数字+类型
class MaJiangNumber: MaJiang {
var number:Int=0
func setNumber(number:Int) {
self.number=number
}
/// 显示牌面
///
/// - Returns: 牌面
override func toString() -> String {
var str:String = "["+String( self.number)
switch self.getType() {
case MaJiangType.Wan:
str = str + "万"
case MaJiangType.Tiao:
str = str + "条"
case MaJiangType.Tong:
str = str + "筒"
default:
str="error"
}
return str+"]、"
}
}
/// 风牌类,此类没有数字 ,只有类型
class MaJiangWind: MaJiang {
/// 返回一张风牌
///
/// - Returns:
override func toString() -> String {
var str:String = "["
switch self.getType() {
case MaJiangType.Dong:
str=str+"东"
case MaJiangType.Nan:
str=str+"南"
case MaJiangType.Xi:
str=str+"西"
case MaJiangType.Bei:
str=str+"北"
case MaJiangType.HongZhong:
str=str+"中"
case MaJiangType.FaCai:
str=str+"发"
case MaJiangType.BaiBan:
str=str+"白"
default:
str="error"
}
str=str+"]、"
return str
}
}
class MaJiangFactory{
/// 麻将工厂类的生成方法,一次只能生成一张麻将
///
/// - Parameter type: 类型
/// - Returns: 返回一张麻将,此时数字牌没有大小
func createMajiang(type:MaJiangType) -> MaJiang {
//一次只能生成一张麻将
var maJiang:MaJiang
if type.rawValue<=3{
maJiang = MaJiangNumber(type: type)
}
else{
maJiang = MaJiangWind(type:type)
}
return maJiang
}
}
/// 骰子类
class Dice{
var number:Int=0
func getNumber()->Int {
return self.number
}
//一次性丢2个骰子
func sendDice() -> Int{
var rm1:Int=0
var rm2:Int=0
var result:Int
for _ in 0..<5{
rm1=Int(arc4random_uniform(6))+1
rm2=Int(arc4random_uniform(6))+1
}
result = rm1+rm2
print(“2个骰子分别是:(rm1):(rm2),结果是(result)”)
return result
}
}
//工具类
class Tools {
/// 返回某一花色的牌,同时按从小到大排序
///
/// - Parameters:
/// - type: 花色类型
/// - maJiangs: 某位玩家的牌
/// - Returns: 根据type返回那个花色的牌。
static func getHuaSeAndSort(type:Int,maJiangs:[MaJiang]) -> [MaJiang] {
var tmp:[MaJiang]=[] //临时数组
//1.先选出这种花色的牌
for x in 0..<maJiangs.count{
if maJiangs[x].getType().rawValue==type{
tmp.append(maJiangs[x])
}
}
//2.进行排序
if tmp.isEmpty || tmp.count==1 {
return tmp //如果为空或只有1个则直接返回空数组
}
if tmp[0].getType().rawValue>3{
return tmp //如果为风直接返回
}
//冒泡法排序
var tmp1:MaJiang
for x in 0..<(tmp.count-1){
for y in 0..<(tmp.count-1-x){
if (tmp[y] as! MaJiangNumber).number > (tmp[y+1] as!MaJiangNumber).number{
tmp1=tmp[y]
tmp[y]=tmp[y+1]
tmp[y+1]=tmp1
}
}
}
return tmp
}
/// 输出一组牌
///
/// - Parameter maJiangs: 一组牌的数组
static func printMaJiangs(maJiangs:[MaJiang]) {
var resultStr=""
for x in 0..<maJiangs.count{
let tmpType=maJiangs[x].getType()
if tmpType==MaJiangType.Wan || tmpType==MaJiangType.Tiao || tmpType==MaJiangType.Tong{
resultStr = resultStr + ( maJiangs[x] as! MaJiangNumber).toString()
}
else{
resultStr = resultStr + (maJiangs[x] as! MaJiangWind).toString()
}
}
print(resultStr)
}
}
/// 游戏主类
class Game {
var maJiangs:[MaJiang]=[] //麻将数组
var players:[Player]=[] //玩家数组
var maJiangFactory:MaJiangFactory=MaJiangFactory() //创建麻将数组
/// 创建玩家
///
/// - Returns: <#return value description#>
func createPlayer() {
print("开始创建玩家。。。")
players.append(Player(id:1,name:"自己"))
players.append(Player(id:2,name:"左"))
players.append(Player(id:3,name:"对家"))
players.append(Player(id:4,name:"右"))
print("创建 \(players.count) 个玩家,玩家创建结束。。。。")
}
/// 创建一幅麻将
func createMaJiang() {
var tmptype:MaJiangType = MaJiangType.Wan //默认值
var tmpMajiang:MaJiangNumber
var tmpMaJiangWind:MaJiangWind
//创建数字牌,x为万条筒,数字 为1-9,每张牌有4张
for x in 1...3 {
if x==1 { tmptype=MaJiangType.Wan}
if x==2 { tmptype=MaJiangType.Tiao}
if x==3 { tmptype=MaJiangType.Tong}
for number in 1...9{
for _ in 0..<4{
tmpMajiang=maJiangFactory.createMajiang(type: tmptype) as! MaJiangNumber
tmpMajiang.setNumber(number: number)
maJiangs.append(tmpMajiang)
}
}
}
for x in 4...10{
if x==4 { tmptype=MaJiangType.Dong}
if x==5 { tmptype=MaJiangType.Nan}
if x==6 { tmptype=MaJiangType.Xi}
if x==7 { tmptype=MaJiangType.Bei}
if x==8 { tmptype=MaJiangType.HongZhong}
if x==9 { tmptype=MaJiangType.FaCai}
if x==10 { tmptype=MaJiangType.BaiBan}
for _ in 0..<4{
tmpMaJiangWind=maJiangFactory.createMajiang(type: tmptype) as! MaJiangWind
maJiangs.append(tmpMaJiangWind)
}
}
print("创建麻将成功。。。。")
// Tools.printMaJiangs(maJiangs: maJiangs)
}
/// 10次洗牌
func changeMaJiang() {
var rm:Int=0 //随机数
var tmp:MaJiang
for x in 1...10{
print("第\(x)次洗牌。。。")
for y in 0..<136{
rm = Int( arc4random_uniform(135)) + 1
tmp=maJiangs[y]
maJiangs[y]=maJiangs[rm]
maJiangs[rm]=tmp
}
}
print("洗牌结束。。。")
// Tools.printMaJiangs(maJiangs: maJiangs)
}
/// 丢骰子后,每人发14张牌
func sendMaJiang() {
let dice=Dice()
var diceNumber = dice.sendDice() //骰子的点数
//从庄家开始,先每人发4张,发3轮,再由庄家取2张
//按点数%4确定谁是庄家,自己是1,左是2,对面是3,右是4
if diceNumber > 4 {
let x:Int = diceNumber%4
if x==0 {
diceNumber=4
}
else{
diceNumber = x
}
}
//实际方位自己1,左2,对面3,右4
print("庄家是\(diceNumber)...")
diceNumber -= 1 //换算成4个方位的数组下标
//现在确定发牌顺序
//记录发牌循序,将发牌顺序记入数组中
var faPaiShunXu:[Int]=[]
for _ in 0..<4{
if diceNumber<4 {
faPaiShunXu.append(diceNumber)
}
else{
faPaiShunXu.append(diceNumber%4)
}
diceNumber += 1
}
//下面开始发牌
var maJiangsId :Int=0//麻将牌中的id下标
//先发3轮,每轮每人4张
for _ in 0..<3{
//每轮要给4个人发牌,根据faPaiShunXu[]的顺序发牌
for y in 0..<4{
//每人每次发4张
for _ in 0..<4{
players[ faPaiShunXu[y] ].playerMaJiangs.append(maJiangs[maJiangsId])
maJiangsId += 1
}
}
}
//庄家连摸2张牌
players[faPaiShunXu[0]].playerMaJiangs.append(maJiangs[maJiangsId])
maJiangsId+=1
players[faPaiShunXu[0]].playerMaJiangs.append(maJiangs[maJiangsId])
//后面3家每人摸一张
maJiangsId+=1
players[faPaiShunXu[1]].playerMaJiangs.append(maJiangs[maJiangsId])
maJiangsId+=1
players[faPaiShunXu[2]].playerMaJiangs.append(maJiangs[maJiangsId])
maJiangsId+=1
players[faPaiShunXu[3]].playerMaJiangs.append(maJiangs[maJiangsId])
// for x in 0..<4{
// print("玩家\(x+1)的牌面是:")
//Tools.printMaJiangs(maJiangs: players[x].playerMaJiangs)
// }
//下面是方法结束}
}
//将每人牌面排序
func soft() {
var tmpMaJiangs:[MaJiang] //临时数组,
var resultMaJiangs:[MaJiang] //某个玩家最后的排序结果
//4个玩家都需要排序
for i in 0..<4{
tmpMaJiangs=[]
resultMaJiangs=[]
//按万条筒。。。。。,10种花色依次排序
for j in 1...10{
tmpMaJiangs=Tools.getHuaSeAndSort(type: j, maJiangs: players[i].playerMaJiangs) //返回的是某个花色排����后的数组
resultMaJiangs += tmpMaJiangs
}
players[i].playerMaJiangs=resultMaJiangs
print("\(i+1)号玩家牌面是:")
Tools.printMaJiangs(maJiangs: players[i].playerMaJiangs)
}
//下面是结束的}
}
func gemaPk() {
}
}
let game=Game()
game.createPlayer()
game.createMaJiang()
game.changeMaJiang()
game.sendMaJiang()
game.soft()
game.gemaPk()
下一篇: 荣耀X30外观好看吗?荣耀X30外观介绍
推荐阅读