欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

swift--广东麻将简化版

程序员文章站 2022-03-06 17:45:33
...

接上篇,本人之前使用一直做微信小程序,现初学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:控制游戏流程
每个方法 和属性都有详细注释
swift--广东麻将简化版

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()

相关标签: swift