结对编程作业

https://github.com/Eden8771/pokergame

 

人员分工博客链接
wang  https://www.cnblogs.com/eden8771/p/15455564.html

一、原型设计

设计说明

https://modao.cc/app/36dafb537ffa7adc978b023d31334d0b248995f8 《扑克牌游戏》 

  • 采用墨刀进行原型设计开发
  • 游戏共有三个界面,分为首页界面,大厅界面和游戏界面
  • 首页界面由游戏标题和三个模式选择的按钮组成,分为联机对战,双人对战和人机对战三种游戏模式

 

游戏界面

规则介绍

 

 

遇到的困难及解决方法

  1. 在原型设计过程中,选择了墨刀作为原型设计工具,墨刀操作简单且美观,适合作为原型工具。
  2. 在创建过程中,一开始不知道可以将界面的几个元件打包成一个母版,导致在旋转界面时异常的麻烦,后通过打包成母版解决了这个问题
  3. 通过此次原型设计,学会了先分析需求,再构想页面,最终通过原型开发工具设计出符合需求的页面,熟悉了原型设计的过程,且对开发工具的使用更加熟练了。

二、原型设计实现

代码实现思路(UI逻辑部分)

从功能角度分析分为三个板块

  • 联机对战
  • 双人对战
  • 人机对战

通过对需求的分析, 因此确定了几个区域:

  1. 牌堆区
  2. (出牌)放置区
  3. 敌我手牌区
  4. 托管区(或者说需要给这个托管按钮找个位置)
    也正是对于敌我手牌区的分析, 知道手牌经常会超过一定的数量. 因此选择了横屏作为显示的方式

 

由于界面的一致性(仅相差被关掉的托管按钮), 因此后文剩余的两个模式的界面将不再展示

  1. 在左下角设定了一个机器人+按钮的形式作为托管的开关
  2. 在右上角设定了"设置"按钮用于调节音量 (因为有配欢乐的BGM斗地主经典音效)
  3. 中心区域为牌堆区与(出牌)放置区
  4. 左上角为对局状态显示
  5. 敌我手牌区分立两边

此时通过接口, 在对方未加入时, 左上角的"对局状态"则会显示对局未开始
当对局开始后, 也就是接收到相应的msg后, 就会相应显示 你的回合/对方回合
只有在自己的回合才会显示 "出牌"/"翻牌" 的按钮. 防止玩家误触
为了防止误触的还有在返回时的确认选项:

代码实现思路(代码逻辑部分)

代码组织与内部实现设计.

  1. 通过各类repository仓库类对不同类型的方法进行了封装, 方便使用, 例如:
  • UIRepository 封装了有关UI方面的方法
  • RobotRepository 则封装了有关机器人出牌方面的算法的方法
  1. 通过对package的命名来进行各种类的分类

算法的关键

    /**
     * 人机返回当前应该出的牌
     * String:
     * 返回牌型则表示该出的牌, 返回空字符串则表示翻牌
     * 算法优先级:
     * ---------------------------------
     *  x:我方手牌 y:对手手牌 z:放置区叠的牌
     *  --------------------------------
     *  1. 必胜条件 (满足后只需要不断翻牌即可获得胜利):
     *      x + 2y + z >= 78
     *  2. 牌库仅剩一张时, 假设手牌中存在该花色牌且当前为机器人回合, 且放置区顶非该花色牌. 则打出该花色牌.
     *  3.  x + z < 5 直接翻牌
     *  4.  x + 1 + z < y  直接翻牌
     *  5.  x > 5 或 z > 5 只出牌
     *      5.1 无牌可打, 翻牌
     *      5.2 有牌可打
     *          5.2.1 优先出手牌中花色数量最多的牌
     *  --------------------------------
  

有价值的代码片段

  • UI代码

    private fun refresh(last: GetGameUUIDLast) {
        if (last.last_code != "") {
            val code = last.last_code.split(" ")
            val player = code[0]
            val operation = code[1]
            val card = code[2]

            if (operation == "0") {
                if (outCards.size > 0 && card[0] == outCards.peek()[0]) {
                    outCards.push(card)
                    val host = intent.getBooleanExtra("host", false)
                    if (player == "0" && host || player == "1" && !host) {
                        for (c in outCards) {
                            myCards.add(c)
                            myCardCount += 1
                        }
                    } else if (player == "1" && host || player == "0" && !host) {
                        for (c in outCards) {
                            enemyCards.add(c)
                            enemyCardCount += 1
                        }
                    }
                    outCards.clear()
                    binding.curCardActivityGame.setImageResource(R.drawable.transparentcard)
                } else {
                    outCards.push(card)
                    binding.curCardActivityGame.setImageResource(UIRepository.cards[card]!!)
                }
            } else if (operation == "1") {
                if (outCards.size > 0 && card[0] == outCards.peek()[0]) {
                    val host = intent.getBooleanExtra("host", true)
                    outCards.push(card)
                    if (player == "0" && host || player == "1" && !host) {
                        for (c in outCards) {
                            myCards.add(c)
                            myCardCount += 1
                        }
                    } else if (player == "1" && host || player == "0" && !host) {
                        for (c in outCards) {
                            enemyCards.add(c)
                            enemyCardCount += 1
                        }
                    }
                    outCards.clear()
                    binding.curCardActivityGame.setImageResource(R.drawable.transparentcard)
                } else {
                    outCards.push(card)
                    binding.curCardActivityGame.setImageResource(UIRepository.cards[card]!!)
                    val host = intent.getBooleanExtra("host", true)
                    if ((player == "0" && host) || (player == "1" && !host)) {
                        myCards.remove(card)
                        myCardCount -= 1
                    } else if ((player == "1" && host) || (player == "0" && !host)) {
                        enemyCards.remove(card)
                        enemyCardCount -= 1
                    }
                }
            }
        }
        binding.myCardsActivityGame.removeAllViews()
        binding.enemyCardsActivityGame.removeAllViews()
        if (myCards.size > 0) {
            myCardCount = 0
            for (c in myCards)
                addMyCard(c)
            binding.myCountActivityGame.text = myCardCount.toString()
        }
        if (enemyCards.size > 0) {
            enemyCardCount = 0
            for (c in enemyCards)
                addEnemyCard(c)
            binding.enemyCountActivityGame.text = enemyCardCount.toString()
        }
        if (isRobot.value == true) {
            isRobot.value = true
        }
    }
fun getRobotCard(x: List<String>, y: List<String>, z: Stack<String>): String {
        Log.d("z", z.toString())
        val totalPile = ArrayList(UIRepository.cards.keys)
        val curPile = totalPile.clone() as ArrayList<String>
        curPile.removeAll(x)
        curPile.removeAll(y)
        curPile.removeAll(z)
        when {
            x.isEmpty() -> {
                return ""
            }
            curPile.size == 1 -> {
                return when {
                    x.size + 1 + z.size < y.size -> ""
                    z.size > 0 -> whenPileOnlyOne(curPile, x, z.peek()[0])
                    else -> whenPileOnlyOne(curPile, x, ' ')
                }
            }
            x.size + 2 * y.size + z.size >= 78 -> {
                return ""
            }
            x.size + z.size <= 5 -> {
                return ""
            }
            x.size + 1 + z.size <= y.size -> {
                return ""
            }
            x.size > 5 -> {
                return if (z.isNotEmpty() && judgeSuitExists(z.peek()[0], x)) {
                    if (z.size > 0)
                        getMostCardFromHand(x, z.peek()[0])
                    else
                        getMostCardFromHand(x, ' ')
                }
                else {
                    getMostCardFromHand(x, ' ')
                }
            }
            z.size > 5 -> {
                return if (judgeSuitExists(z.peek()[0], x)) {
                    if (z.size > 0)
                        getMostCardFromHand(x, z.peek()[0])
                    else
                        getMostCardFromHand(x, ' ')
                }
                else {
                    getMostCardFromHand(x, ' ')
                }
            }
            else -> {
                return ""
            }
        }
    }

传入的参数为上文注释中的x,y,z. 通过对三个参数的分析.
根据自己指定的算法, 希望能够得出一个出牌的较优解.

展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路

单元测试代码:

class ExampleUnitTest {
     /**
     * 人机返回当前应该出的牌
     * String:
     * 返回牌型则表示该出的牌, 返回空字符串则表示翻牌
     * 算法优先级:
     * ---------------------------------
     *  x:我方手牌 y:对手手牌 z:放置区叠的牌
     *  --------------------------------
     *  1. 必胜条件 (满足后只需要不断翻牌即可获得胜利):
     *      x + 2y + z >= 78
     *  2. 牌库仅剩一张时, 假设手牌中存在该花色牌且当前为机器人回合, 且放置区顶非该花色牌. 则打出该花色牌.
     *  3.  x + z < 5 直接翻牌
     *  4.  x + 1 + z < y  直接翻牌
     *  5.  x > 5 或 z > 5 只出牌
     *      5.1 无牌可打, 翻牌
     *      5.2 有牌可打
     *          5.2.1 优先出手牌中花色数量最多的牌
     *  --------------------------------
     *牌的花色 D方块 S黑桃 H红桃 C梅花
     */

    /**
     * 测试必胜规则,此时只翻牌
     */
    @Test
    fun test1() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("D1","D2","D3","D4","D5","D6","D7"))
        y.addAll(listOf("DJ","DQ","DK","S4","S5","S6","S7","S8","S9","H1","H2","H4","C5","C7","C8","C9","CJ","C10","C1","HK","H7","C4","C6","C2","D10","D9","H6","HK","HQ","H10","H3","D8","S2"))
        z.addAll(listOf("S3","S4","S5","S9","S10","SK"))
        assertEquals("",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     * 测试规则2,此时打出牌库中剩下唯一一张花色的牌
     */
    @Test
    fun test2() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("D1","D3","S10","SJ","SQ","S1","D2","S3","D4","C3","D5","D6","D7","CQ","S7","S8","S9","H1","H2","H4","C5","C7","C8","C9","CJ","C10","C1","HK","H7","C4","C6","C2"))
        y.addAll(listOf("DJ","DQ","DK","S4","S5","S6","D10","D9","H6","HJ","HQ","H10","H3","D8","S2"))
        z.addAll(listOf("CK","H5","H8","H9"))
        assertEquals("S10",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     *  测试规则3,此时x + z < 5,直接翻牌
     */
    @Test
    fun test3() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("H1","C2","D3"))
        y.addAll(listOf("H4","S10"))
        z.addAll(listOf("HJ"))
        assertEquals("",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     *  测试规则4,此时应直接翻牌
     */
    @Test
    fun test4() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("HJ","C2","SK","D6","H6"))
        y.addAll(listOf("DK","S4","S5","S6","S7","S8","S9","H1","H2","H4","C5"))
        z.addAll(listOf("H8","C10","D1","C1"))
        assertEquals("",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     *  测试规则5,此时x > 5 或 z > 5 选择出牌,且有牌可打符合5.2.1,选择出手牌中与放置区顶不相同的牌打出
     */
    @Test
    fun test5() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("C9","H3","HJ","C2","SK","D6","H6"))
        y.addAll(listOf("DK","S4","S5","S6","S7","S8","S9","H1","H2","H4","C5"))
        z.addAll(listOf("C10","D1","C1","H8"))
        assertEquals("C9",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     *  测试6,此时x > 5 或 z > 5 选择出牌,但无牌可打,符合5.1,选择翻牌
     */
    @Test
    fun test6() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf())
        y.addAll(listOf("DK","S4","S5","S6","S9","H1","H2","H4","C5"))
        z.addAll(listOf("H8","C10","D1","C1","S7","S8","HK","H7","C4","C6","C2","D10"))
        assertEquals("",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     *  测试7,此时x > 5 或 z > 5 选择出牌,且有牌可打符合5.2.1,选择出手牌中与放置区顶不相同的牌打出
     */
    @Test
    fun test7() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("C9","H3","HJ","C2","SK","D6","H6"))
        y.addAll(listOf("DK","S4","S5","S6","S7","S8","S9","H1","H2","H4","C5"))
        z.addAll(listOf("CQ","H8","C10","D1","C1"))
        assertEquals("H3",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     *  测试8,此时x > 5 或 z > 5 选择出牌,且有牌可打符合5.2.1,选择出手牌中与放置区顶不相同的牌打出
     */
    @Test
    fun test8() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("C9","C2","H3","HJ","SK","D6","H6"))
        y.addAll(listOf("DK","S4","S5","S6","S7","S8","S9","H1","H2","H4","C5"))
        z.addAll(listOf("CQ","H8","C10","D1","C1"))
        assertEquals("H3",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     *  测试9,随机情况测试
     */
    @Test
    fun test9() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("CJ","C10","C1","HK","H7","C4","C6","C2","D10"))
        y.addAll(listOf("DK","S4","C5","H6","S7","S8","S9","H1","H2","H4","C5","D1","SJ","C3"))
        z.addAll(listOf("H8","C10","D1","C9","D8","CQ"))
        assertEquals("HK",RobotRepository.getRobotCard(x, y, z))
    }
     /**
     *  测试10,随机情况测试
     */
    @Test
    fun test10() {
        val x = ArrayList<String>()
        val y = ArrayList<String>()
        val z = Stack<String>()
        x.addAll(listOf("C4","C6","C2","D10","C6","C2","D10","D9","H6","HK"))
        y.addAll(listOf("DK","S4","C5","H6","S7","S8","S9","H1","H2","H4","C5","D1","SJ","C3","CJ","C10","C1","HK","H7"))
        z.addAll(listOf("CQ","H8","C10","D1","C9","D8"))
        assertEquals("",RobotRepository.getRobotCard(x, y, z))
    }
}

评价我的队友

因为我没有队友,那我只能自评了,感觉很差,找素材结果没找到免费素材,一副扑克牌素材需要5$,内心很纠结,也影响了完成进度。

此次结对作业的PSP和学习进度条

第N周新增代码(行)累计代码(行)本周学习耗时(小时)累计学习耗时(小时)重要成长
1 0 0 24 24 寻找完成制作此次小游戏的软件unity,并且去学习了unity制作2d小游戏的一系列教程。
2 2000+ 2000+ 0 24 感觉写完了就摸鱼
3 0 2000+ 0 24
4 0 2000+ 0 24

三、心得

作业难度

一个人比较无力

作业感想

没有能够找到的队友是我最大的问题

对之后学习的启发

初步学习了对于游戏制作的方法,去寻找什么软件进行制作,我在这里选择了unity,并且去参考学习了unity制作其他2d小游戏的一些教程。增加了自身对于游戏制作的认识,以及对于UI设计的一系列知识。

posted @ 2021-10-24 20:31  亿平  阅读(81)  评论(0)    收藏  举报