目录
第一章 需求分析 4
1 引言 4
1.1编写目的 4
1.2背景 4
2 任务概述 4
2.1目标 4
2.2用户的特点 5
2.3假定和约束 5
3 需求规定 5
3.1对功能的规定 5
3.2对性能的规定 13
3.3输入输出要求 14
3.4数据管理能力要求 15
3.5故障处理要求 15
4 运行环境规定 15
4.1设备 15
4.2支持软件 15
第二章 概要设计 16

  1. 软件开发任务 16
    1.1 开发目标 16
    1.2 运行环境 16
    1.3 需求概述 16
    1.4 程序限制 17
  2. 总体设计 17
    2.1 总体结构 17
    2.2 用户端模块 18
    2.3 服务器端模块 18
    2.4 处理流程 19
  3. 数据结构 20
    3.1 棋盘类 20
    3.2 玩家类 21
    3.3 历史记录 21
    3.4 通讯数据 21
    3.5 服务器端数据表 21
  4. 模块设计 23
    4.1 流程控制模块 23
    4.2 用户接口模块 23
    4.3 机器算法模块 25
    4.4 对盘管理模块 26
  5. 异常处理及其它 26
    5.1 异常处理 26
    5.2 安全性与维护 27
    5.3 扩展功能 27
    第三章 详细设计 28
    1 引言 28
    1.1编写目的 28
    1.2背景 28
    1.3定义 28
    1.4参考资料 28
    2 程序系统的结构 29
    3 流程控制模块 29
    3.1程序描述 29
    3.2性能 30
    3.3接口 30
    3.4流程逻辑 31
    4 机器算法模块 33
    4.1程序描述 33
    4.2性能 33
    4.3算法 34
    4.4接口 35
    4.5其它设想 35
  6. 用户交互模块 35
    5.1 概述 35
    5.2 功能 36
    5.3 输入项 36
    5.4 输出项 36
    5.5 流程逻辑 36
    5.6 限制条件 38
    6 Manila通信协议 38
    6.1 Manila请求报文 38
    6.2 Manila响应报文 38
    6.3 对象封装: 39
    7 服务器端用户登录管理模块 39
    7.1程序描述 39
    7.2功能 39
    7.3性能 40
    7.4输入项 40
    7.5输出项 40
    7.6对象封装 40
    8 服务端对局管理模块 42
    8.1程序描述 42
    8.2功能 42
    8.3性能 42
    8.4输入项 42
    8.5输出项 43
    8.6对象封装 43
    9 服务端用户注册模块 44
    9.1程序描述 44
    9.2功能 44
    9.3性能 44
    9.4输人项 45
    9.5输出项 45
    10 服务器配置 45
    10.1 主机 45
    10.2 硬件环境 45
    10.3 软件环境 45
    第四章 桌游马尼拉软件的测试方案 46
    1.概述 46
    1.1背景 46
    说明: 46
    a.软件系统的名称:桌游马尼拉的PC端实现。 46
    b.任务提出者:“软件工程原理”课程教师黄舟 46
    开发者:软工第二小组成员() 46
    用户:软工课程教师、选课同学及其他可能的游戏玩家 46
    运行网络;广域网环境 46
    由于我们组是第一次开发软件,因此在开发过程中可能会出现较大问题并且影响用户体验,因而需要对软件进行测试。 46
    1.2测试目的与用途 47
    目的:暴露软件中隐藏的错误和缺陷,以便用户在使用过程中有更好的体验,并且决定使用开发的软件作为娱乐工具。 47
    用途:找出软件开发过程中未注意到的漏洞,加以改正,更好地实现软件的服务功能。 47
    2.系统需求 47
    2.1功能需求 47
    具体可以参考需求说明文档。其中主要包括用户登录、用户管理、数据传输、游戏模式选择、竞选总督、总督操作、放置随从、掷骰子、船进港、领航员操作、海盗登穿、一般随从盈利、股票上涨、游戏结束、结算和抵押股票等功能。 47
    2.2性能需求 47
    由于本软件为轻量级软件,而且供娱乐使用,而且希望模拟真实场景体验,因而规定时间特性要求,在网络带宽良好的情况下: 47
    响应时间:毫秒级 47
    更新处理时间;毫秒级 47
    数据的转换和传送时间;毫秒级 47
    电脑AI反应时间:秒级 47
    精度和有效时限的变化:在毫秒级的实现 47
    另外,还需要对用户的文本输入错误进行处理。 47
    2.3其他需求 47
    服务器的数据管理需求:实现局域网内百级用户数据的管理。 47
    客户端的数据管理需求:实现对于历史游戏结果的保存管理,可达百次级别。 47
    输入数据主要为整形数据和鼠标的位置信息,需要对位置信息进行阈值处理。 47
    图形界面主要包括五个层次: 47
    登录界面:背景图、相应的玩家盈利信息和、“单人游戏”、“多人游戏”、“历史记录”、“成就”、“商城”五大按键。 47
    “单人游戏”、“多人游戏”:马尼拉桌游背景图、可移动船只、船员、四位玩家、道具面板、资金输入面板、船员放置位置。游戏完成若达成成就自动弹出提示信息。 47
    “历史记录”:往期游戏数据面板和个人评价等。 47
    “成就”:完成任务点亮图标。 47
    “商城”:人物形象、新的货物等,玩游戏获得资源,资源用于在商城购买 47
    3.测试计划 47
    3.1测试进度 47
    3.2测试环境 48
    3.3测试工具 48
    4.测试方案 48
    4.1测试项目确认 48
    4.2测试分析 48
    4.3测试用例设计 50
    由于服务器出了部分问题,没有调试畅通,所以用户管理、用户登陆和数据传输没有办法测试。其余部分没有比较好的组合,于是就逐项测试,没有整体测试。 50
    4.4非功能测试用例 51

第二章 概要设计

1.软件开发任务
1.1开发目标
遵循桌游的整体流程和规则,将桌游马尼拉在PC端实现,并配以美观友好的界面。玩家可以选择单人模式与机器算法对战,也可以选择多人模式与网络上的其他玩家联网对战。开发期限为本学期末。
1.2运行环境
客户端硬件环境:客户端要求x86或x86-64处理器,性能高于Intel Core i5-5200U,需要128MB或以上可用内存和150M可用外存;软件环境:程序面向Windows系统开发,客户端需要安装Python3.x及必要的第三方库
服务器硬件环境:基于KVM搭建,CPU: QEMU Virtual CPU version (cpu64-rhel6),RAM: 520MB,DISK: 10G SSD。软件环境:基于CentOS release 6.8,除此之外还需要安装MySQL。
1.3需求概述
功能:1)实现游戏流程的控制,包括按时向玩家发出信息、获取玩家决策;维护当前游戏状况(个人财产,随从和船的位置,货物股价);产生随机数推动船前进;自动判定胜负。2)实现对局的管理和信息在网络中的传输(两位或以上人类玩家时)。3)实现能够模拟人类做出决策的机器算法。4)实现用户信息的管理。
性能:精度方面,游戏中只用到整数,不涉及浮点误差;时间方面,要求程序在毫秒级时间内响应、传输数据、更新显示;机器算法在秒级时间内作出反应。
此外,要求程序能通过图形用户界面与玩家交互;管理玩家信息和历史对局数据;处理网络故障、游戏中的不合法操作等错误。
1.4程序限制
同时处理的并行用户数为百级,不能超过服务器的处理能力。
服务器端存储空间有限,本文转载自http://www.biyezuopin.vip/onews.asp?id=14887能够保存的复盘数据有上限,或者需要超级管理员每隔一定时间将数据从远端进行备份。

2.总体设计
2.1总体结构
本程序采用C-S框架,即分为服务器端和用户端。服务器端主要负责安排对局以及玩家决策信息在网络间的传输,其余流程控制、游戏状态的更新和显示均在用户端完成。服务器端和用户端各有一个基于TCP/IP协议的通信模块,用于消息的传输。

import random
from time import *Stockprice=[0,5,10,20,30] # 股票价格
# 四种货物(1-4表示,下同。船只与所载货物编号相同,没有单独的编号)
GOOD_CIST=1 # 肉苁蓉
GOOD_SILK=2 # 丝绸
GOOD_GINS=3 # 人参
GOOD_JADE=4 # 玉石
GOOD_GAIN=[0,24,30,18,36]
# 位置表
POS_COST=[-1 for i in range(100)]
POS_GAIN=[-1 for j in range(100)]
# 11-44:船上位置(十位数代表货物,个位数从前往后)
POS_COST[11]=2
POS_COST[12]=3
POS_COST[13]=4
POS_COST[21]=3
POS_COST[22]=4
POS_COST[23]=5
POS_COST[31]=1
POS_COST[32]=2
POS_COST[33]=3
POS_COST[41]=3
POS_COST[42]=4
POS_COST[43]=5
POS_COST[44]=5
# 51-53 码头;61-63 修理厂
POS_COST[51]=POS_COST[61]=4
POS_GAIN[51]=POS_GAIN[61]=6
POS_COST[52]=POS_COST[62]=3
POS_GAIN[52]=POS_GAIN[62]=8
POS_COST[53]=POS_COST[63]=2
POS_GAIN[53]=POS_GAIN[63]=12
# 71-72 领航
POS_COST[71]=2 # 小领航
POS_COST[72]=5 # 大领航
# 81-82 海盗
POS_COST[81]=POS_COST[82]=5 # 81为海盗船长,82为海盗船员
# 91 保险公司
POS_COST[91]=0
POS_GAIN[91]=10class Player:def __init__(self,name="default"):self.name=nameself.turn=-1self.board=None# 玩家名,一个字符串returndef bid(self,Curprice=0):# Curprice:当前报价return (-1,0) # -1代表退出竞拍,0代表不抵押股票def master(self):return random.choice([(3,3,3,-1,0,0),(3,3,-1,3,0,0),(3,-1,3,3,0,0),(-1,3,3,3,0,0)])# 前三种货物装船,起点为3;不购买股票,不抵押股票def place_retinue(self):return (0,0) # 0代表不放置随从(空位置,0代表不抵押股票def move_boat(self,type):# type为1:小领航,type为2:大领航return (0,0,0,0) # 所有船只不移动def pirateII(self,type,captain_pos=-1):# type为1:海盗船长,此时captain_pos为空# type为2:海盗船员,此时captain_pos为船长登船位置return 0 # 不登船def pirateIII(self,type,captain_boat=-1,captain_choice=5):# type为1:海盗船长,此时后两个参数无意义# type为2:海盗船员,此时captain_boat为船长所选船的货物类型(1-4)# captain_choice为该船的去向(5代表港口,6代表修理厂)return (0,5) # 第一个返回值为所选船的货物类型,第二个返回值为船的去向class Board:def __init__(self,players):self.players= playersfor p in range(4):players[p].turn=pplayers[p].board=self# 棋盘状态# 与货物有关的列表为了可以1,2,3,4直接引用,长度为5,下同self.stockprice=[-1,0,0,0,0]self.stockremain=[-1,5,5,5,5]self.pos_state=[-1 for k in range(100)]# -1:空;0-3:被该玩家占据;6:当前不可用;9:永久不可用for pos in range(100):if POS_COST[pos]==-1:self.pos_state[pos]=9self.boat_pos=[-1,-1,-1,-1,-1]# 0-13 棋盘位置;51-53 港口;61-63 修理厂self.dice = [-1, -1, -1, -1, -1]# 玩家状态# 与玩家对应的列表长度为4,玩家用0-3标识,下同self.stocknum=[[-1,0,0,0,0] for i in range(4)]self.curmoney=[30,30,30,30]self.curtotal=[30,30,30,30]self.bidprice=[0,0,0,0] # 修订规则:总督起拍价格为0元# 根据西方经济学理论,取消价格控制可以带来更有效的市场结果:)self.stockpledge=[0,0,0,0]self.curmaster=-1self.curround=0self.curstage=0self.harbour_boats = 0self.repair_boats = 0returndef game_process(self):# 建立log文件log=open(strftime("%Y%m%d_%H%M%S", localtime())+".log","w")log.write("Player1:"+self.players[0].name+"\n")log.write("Player2:" + self.players[1].name + "\n")log.write("Player3:" + self.players[2].name + "\n")log.write("Player4:" + self.players[3].name + "\n")log.write(strftime("%H:%M:%S", localtime())+" Manila begins\n")# 发放原始股票for p in range(4):for loop in range(2):s=0while self.stockremain[s]<=2:s=random.randint(1,4)self.stocknum[p][s]+=1self.stockremain[s]-=1log.write(strftime("%H:%M:%S", localtime()) \+" Assign stock "+str(s)+" to player"+str(p+1)+"\n")while(self.stockprice[1]<30 and self.stockprice[2]<30and self.stockprice[3]<30 and self.stockprice[4]<30):# 新一轮游戏,初始化for pos in range(100):if  not self.pos_state[pos]==9:self.pos_state[pos]=-1self.pos_state[82]=6 # 无海盗船长时不能当海盗船员self.boat_pos=[-1,-1,-1,-1,-1]self.bidprice = [0,0,0,0]self.curround += 1log.write(strftime("%H:%M:%S", localtime()) + " Start of Round " + str(self.curround) + "\n")self.curstage = 0self.harbour_boats = 0self.repair_boats = 0# 竞选总督curprice=-1if self.curround>1:p=self.curmasterelse:p=0self.curmaster = -1while self.bidprice.count(-1)<3:# 这一条件意味着如果前三个人不竞选,第四位玩家自动成为总督if not self.bidprice[p]==-1:(self.bidprice[p],pledge)=self.players[p].bid(curprice)# 处理股票抵押# 要求竞选时报价不超过手中现金,如果钱不够,只有抵押了股票才有报价的权力# 即使没有竞选成功,股票也已经抵押了。if pledge>0:if pledge>self.stocknum[p][1]+self.stocknum[p][2]+self.stocknum[p][3]+\self.stocknum[p][4]-self.stockpledge[p]:raise Exception("Invalid pledge")else:self.stockpledge[p]+=pledgeself.curmoney[p]+=10*pledgelog.write(strftime("%H:%M:%S", localtime())\+" Player"+str(p+1)+" pledges "+str(pledge)+" stocks\n")# 处理竞价if self.bidprice[p]>self.curmoney[p]:raise Exception("Invalid bid:Lack of money")if self.bidprice[p]>curprice:curprice=self.bidprice[p]elif not self.bidprice[p]==-1:raise Exception("Invalid bid")p=(p+1)%4# 总督行使职权for p in range(4):if self.bidprice[p]>=0:self.curmaster=pself.curmoney[p]-=max(curprice,0)log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(p + 1) + " becomes the master at a pr"\+"ice of " + str(max(curprice,0))+"\n")(self.boat_pos[1],self.boat_pos[2],self.boat_pos[3],self.boat_pos[4],\stocktype,pledge)=self.players[self.curmaster].master()# 处理抵押股票if pledge > 0:if pledge > self.stocknum[self.curmaster][1] + self.stocknum[self.curmaster][2]+\self.stocknum[self.curmaster][3] + self.stocknum[self.curmaster][4]-\self.stockpledge[self.curmaster]:raise Exception("Invalid pledge")else:self.stockpledge[self.curmaster] += pledgeself.curmoney[self.curmaster] += 10 * pledgelog.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(self.curmaster+1) + " pledges " + str(pledge) + " stocks\n")# 处理船初始位置if not self.boat_pos.count(-1)==2:raise Exception("Invalid assignment")pos_sum=0for b in range(1,5):if self.boat_pos[b]>5:raise Exception("Invalid assignment")if not self.boat_pos[b]==-1:pos_sum+=self.boat_pos[b]else:for pos in range(10*b+1,10*b+5):if self.pos_state[pos]==-1:self.pos_state[pos]=6if not pos_sum==9:raise Exception("Invalid assignment")log.write(strftime("%H:%M:%S", localtime()) + " Player" \+ str(self.curmaster+1) + " assigns boats at " + str(self.boat_pos[1:])+"\n")# 处理购买股票if stocktype>0:curcost=min(10,self.stockprice[stocktype])if self.curmoney[self.curmaster]<curcost:raise Exception("Invalid purchase of stock:lack of money")elif self.stockremain[stocktype]<=0:raise Exception("Invalid purchase of stock:no available stock")else:self.stockremain[stocktype]-=1self.stocknum[self.curmaster][stocktype]+=1self.curmoney[self.curmaster]-=curcostlog.write(strftime("%H:%M:%S", localtime()) + " Player" \+ str(self.curmaster + 1) + " buys stock of " + str(stocktype) + "\n")self.curstage=1# 第一轮放置随从p=self.curmasterfor turn in range(4):(place,pledge)=self.players[p].place_retinue()# 处理抵押股票if pledge > 0:if pledge > self.stocknum[p][1] + self.stocknum[p][2] + self.stocknum[p][3] + \self.stocknum[p][4] - self.stockpledge[p]:raise Exception("Invalid pledge")else:self.stockpledge[p] += pledgeself.curmoney[p] += 10 * pledgelog.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(p+1) + " pledges " + str(pledge) + " stocks\n")# 处理随从放置if place>0:if not self.pos_state[place]==-1:raise Exception("Invalid placement of retinue")elif POS_COST[place]>self.curmoney[p]:raise Exception("Invalid placement of retinue:lack of money")else:self.pos_state[place]=pself.curmoney[p]-=POS_COST[place]if place==91:self.curmoney+=10if place==81 and self.pos_state[82]==6:self.pos_state[82] = -1log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(p + 1) + " places retinue at position " + str(place) + "\n")p=(p+1)%4# 第一轮投骰子for b in range(1,5):self.dice[b]=random.randint(1,6)if self.boat_pos[b]>=0:self.boat_pos[b]+=self.dice[b]log.write(strftime("%H:%M:%S", localtime()) \+ " Dice for Good " + str(b) + ": " + str(self.dice[b]) + "\n")self.curstage=2# 第二轮放置随从p = self.curmasterfor turn in range(4):(place, pledge) = self.players[p].place_retinue()# 处理抵押股票if pledge > 0:if pledge > self.stocknum[p][1] + self.stocknum[p][2] + self.stocknum[p][3] + \self.stocknum[p][4] - self.stockpledge[p]:raise Exception("Invalid pledge")else:self.stockpledge[p] += pledgeself.curmoney[p] += 10 * pledgelog.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(p+1) + " pledges " + str(pledge) + " stocks\n")# 处理随从放置if place > 0:if not self.pos_state[place] == -1:raise Exception("Invalid placement of retinue")elif POS_COST[place] > self.curmoney[p]:raise Exception("Invalid placement of retinue:lack of money")else:self.pos_state[place] = pself.curmoney[p] -= POS_COST[place]if place == 91:self.curmoney[p] += 10if place==81 and self.pos_state[82]==6:self.pos_state[82] = -1log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(p + 1) + " places retinue at position " + str(place) + "\n")p = (p + 1) % 4# 第二轮投骰子for b in range(1, 5):self.dice[b] = random.randint(1, 6)if self.boat_pos[b] >= 0:self.boat_pos[b] += self.dice[b]log.write(strftime("%H:%M:%S", localtime()) \+ " Dice for Good " + str(b) + ": " + str(self.dice[b]) + "\n")if self.boat_pos[b]>13:self.harbour_boats += 1self.boat_pos[b]=50+self.harbour_boatsif self.pos_state[self.boat_pos[b]]==-1:self.pos_state[self.boat_pos[b]]=6for _pos in range(1,5):if self.pos_state[b*10+_pos]==-1:self.pos_state[b*10+_pos] = 6log.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(b) + " reaches the harbour\n")# 第二轮海盗登船if self.boat_pos.count(13)>=1 and not self.pos_state[81]==-1:replace1=self.players[self.pos_state[81]].pirateII(1)if not replace1 in [0,11,12,13,21,22,23,31,32,33,41,42,43,44]:raise Exception("Invaid replace position")if replace1>0:if self.boat_pos[replace1/10]!=13:raise Exception("Invaid replace position:boat not available")else:self.pos_state[replace1]=self.pos_state[81]log.write(strftime("%H:%M:%S", localtime()) \+ " Pirate captain Player" + str(self.pos_state[81] + 1) + " launches position " + str(replace1) + "\n")self.pos_state[81] = -1if not self.pos_state[82]==-1:replace2 = self.players[self.pos_state[82]].pirateII(2,replace1)if not replace2 in [0, 11, 12, 13, 21, 22, 23, 31, 32, 33, 41, 42, 43, 44]:raise Exception("Invaid replace position")if replace2 > 0:if self.boat_pos[replace2 / 10] != 13:raise Exception("Invaid replace position:boat not available")elif replace2==replace1:raise Exception("Invaid replace position:cannot replace captain")else:self.pos_state[replace2] = self.pos_state[82]log.write(strftime("%H:%M:%S", localtime()) \+ " Pirate sailor Player" + str(self.pos_state[82] + 1) + " launches position " + str(replace2) + "\n")self.pos_state[82] = -1if self.pos_state[81]==-1 and not self.pos_state[82]==-1:self.pos_state[81]=self.pos_state[82]self.pos_state[82] = -1if self.harbour_boats<3:self.curstage = 3# 第三轮放置随从p = self.curmasterfor turn in range(4):(place, pledge) = self.players[p].place_retinue()# 处理抵押股票if pledge > 0:if pledge > self.stocknum[p][1] + self.stocknum[p][2] + self.stocknum[p][3] + \self.stocknum[p][4] - self.stockpledge[p]:raise Exception("Invalid pledge")else:self.stockpledge[p] += pledgeself.curmoney[p] += 10 * pledgelog.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(p + 1) + " pledges " + str(pledge) + " stocks\n")# 处理随从放置if place > 0:if not self.pos_state[place] == -1:raise Exception("Invalid placement of retinue")elif POS_COST[place] > self.curmoney[p]:raise Exception("Invalid placement of retinue:lack of money")else:self.pos_state[place] = pself.curmoney[p] -= POS_COST[place]if place == 91:self.curmoney[p] += 10if place == 81 and self.pos_state[82] == 6:self.pos_state[82] = -1log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(p + 1) + " places retinue at position " + str(place) + "\n")p = (p + 1) % 4# 领航员操纵船只if not self.pos_state[71]==-1:move=self.players[self.pos_state[71]].move_boat(1)if abs(move[0])+abs(move[1])+abs(move[2])+abs(move[3])>1:raise Exception("Invalid move")else:for b in range(1,5):if self.boat_pos[b]>0 and self.boat_pos[b]<=13:self.boat_pos[b]=max(self.boat_pos[b]+move[b-1],0)# 相当于直接排除了错误移动未启用和已进港船只的情况,视为没有移动if self.boat_pos[b]>13:self.harbour_boats += 1self.boat_pos[b] = 50 + self.harbour_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(b) + " reaches the harbour\n")log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(self.pos_state[71] + 1) + " moves boats: " + str(move) + "\n")if not self.pos_state[72]==-1:move=self.players[self.pos_state[72]].move_boat(2)if abs(move[0])+abs(move[1])+abs(move[2])+abs(move[3])>2:raise Exception("Invalid move")else:for b in range(1,5):if self.boat_pos[b]>0 and self.boat_pos[b]<=13:self.boat_pos[b]=max(self.boat_pos[b]+move[b-1],0)if self.boat_pos[b]>13:self.harbour_boats += 1self.boat_pos[b] = 50 + self.harbour_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(b) + " reaches the harbour\n")log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(self.pos_state[72] + 1) + " moves boats: " + str(move) + "\n")# 掷第三轮骰子for b in range(1, 5):self.dice[b] = random.randint(1, 6)if self.boat_pos[b] >= 0 and self.boat_pos[b] <=13:self.boat_pos[b] += self.dice[b]log.write(strftime("%H:%M:%S", localtime()) \+ " Dice for Good " + str(b) + ": " + str(self.dice[b]) + "\n")if self.boat_pos[b] > 13:self.harbour_boats += 1self.boat_pos[b] = 50 + self.harbour_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(b) + " reaches the harbour\n")# 第三轮海盗登船if self.boat_pos.count(13) >= 1 and not self.pos_state[81] == -1:(hijack1,direc1) = self.players[self.pos_state[81]].pirateIII(1)if not hijack1 in [0,1,2,3,4]:raise Exception("Invaid hijack")if hijack1 > 0:if self.boat_pos[hijack1] != 13:raise Exception("Invaid hijack:boat not available")else:for pos in range(hijack1*10+1,hijack1*10+5):if not self.pos_state[pos]==9:self.pos_state[pos] =-1self.pos_state[hijack1*10+1]=self.pos_state[81]log.write(strftime("%H:%M:%S", localtime()) + " Pirate captain Player"\+ str(self.pos_state[81] + 1) + " hijacks boat " + str(hijack1) + "\n")self.pos_state[81] = -1if not self.pos_state[82] == -1:(hijack2,direc2) = self.players[self.pos_state[82]].pirateIII(2, hijack1,direc1)if not hijack2 in [0,1,2,3,4]:raise Exception("Invaid hijack")if hijack2 > 0:if self.boat_pos[hijack2] != 13:raise Exception("Invaid hijack:boat not available")elif hijack2 == hijack1:self.pos_state[hijack1 * 10 + 2] = self.pos_state[82]log.write(strftime("%H:%M:%S", localtime()) + " Pirate sailor Player" \+ str(self.pos_state[82] + 1) + " hijacks boat " + str(hijack1) + "\n")self.pos_state[82] = -1if direc1==5:self.harbour_boats += 1self.boat_pos[hijack1] = 50 + self.harbour_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(hijack1) + " reaches the harbour\n")elif direc1==6:self.repair_boats += 1self.boat_pos[hijack1] = 60 + self.repair_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(hijack1) + " goes to the repair factory\n")else:for pos in range(hijack2 * 10 + 1, hijack2 * 10 + 5):if not self.pos_state[pos] == 9:self.pos_state[pos] = -1self.pos_state[hijack2 * 10 + 1] = self.pos_state[82]self.pos_state[82] = -1log.write(strftime("%H:%M:%S", localtime()) + "Pirate sailor Player" \+ str(self.pos_state[82] + 1) + " hijacks boat" + str(hijack2) + "\n")if direc1==5:self.harbour_boats += 1self.boat_pos[hijack1] = 50 + self.harbour_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(hijack1) + " reaches the harbour\n")elif direc1==6:self.repair_boats += 1self.boat_pos[hijack1] = 60 + self.repair_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(hijack1) + " goes to the repair factory\n")if direc2==5:self.harbour_boats += 1self.boat_pos[hijack2] = 50 + self.harbour_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(hijack2) + " reaches the harbour\n")elif direc2==6:self.repair_boats += 1self.boat_pos[hijack2] = 60 + self.repair_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(hijack2) + " goes to the repair factory\n")# 所有船确定去向for b in range(1,5):if self.boat_pos[b]>=0 and self.boat_pos[b]<13:self.repair_boats += 1self.boat_pos[b] = 60 + self.repair_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(b) + " goes to the repair factory\n")elif self.boat_pos[b]==13:self.harbour_boats += 1self.boat_pos[b] = 50 + self.harbour_boatslog.write(strftime("%H:%M:%S", localtime()) \+ " Good " + str(b) + " reaches the harbour\n")assert self.harbour_boats+self.repair_boats==3# 股票涨价、进港船员分配利润for b in range(1,5):if self.boat_pos[b]//10==5: # 顺利进港self.stockprice[b]+=5+(self.stockprice[b]>=10)*5sailor=0for pos in range(10*b+1,10*b+5):if self.pos_state[pos]>=0 and self.pos_state[pos]<=3:sailor+=1if sailor>0:for pos in range(10 * b + 1, 10 * b + 5):if self.pos_state[pos] >= 0 and self.pos_state[pos] <= 3:self.curmoney[self.pos_state[pos]]+=GOOD_GAIN[b]//sailorlog.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(self.pos_state[pos]+1) + " gets "\+str(GOOD_GAIN[b]//sailor)+" from boat "+str(b)+"\n")# 码头、修理厂获利for pos in range(51,54):if self.pos_state[pos]>=0 and self.pos_state[pos] <= 3\and 50+self.harbour_boats>=pos:self.curmoney[self.pos_state[pos]]+=POS_GAIN[pos]log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(self.pos_state[pos] + 1) + " gets " \+ str(POS_GAIN[pos]) + " from position " + str(pos) + "\n")for pos in range(61,64):if self.pos_state[pos]>=0 and self.pos_state[pos] <= 3\and 60+self.repair_boats>=pos:self.curmoney[self.pos_state[pos]]+=POS_GAIN[pos]log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(self.pos_state[pos] + 1) + " gets " \+ str(POS_GAIN[pos]) + " from position " + str(pos) + "\n")# 保险代理人赔付if self.repair_boats>0 and self.pos_state[91]>=0\and self.pos_state[91]<=3:loss=[0,6,14,29]self.curmoney[self.pos_state[91]]-=loss[self.repair_boats]log.write(strftime("%H:%M:%S", localtime()) \+ " Player" + str(self.pos_state[91] + 1) + " pays " \+ str(min(loss[self.repair_boats],self.curmoney[self.pos_state[91]])) + " for insurance\n")self.curmoney[self.pos_state[91]]=max(0,self.curmoney[self.pos_state[91]])# 计算本轮排名for p in range(4):self.curtotal[p]=self.curmoney[p]-15*self.stockpledge[p]for b in range(1,5):self.curtotal[p]+=self.stockprice[b]*self.stocknum[p][b]log.write(strftime("%H:%M:%S", localtime()) + " End of Round "+str(self.curround)+"\n")log.write(strftime("%H:%M:%S", localtime()) + " Stock price:"+str(self.stockprice[1:])+"\n")for p in range(4):log.write(strftime("%H:%M:%S", localtime()) + " Player"+str(p+1)+":"+ str(self.curmoney[p]) + " " + str(self.curtotal[p] - self.curmoney[p] + 15 * self.stockpledge[p]) + " -" + str(15 * self.stockpledge[p]) + " " + str(self.curtotal[p]) + "\n")log.write(strftime("%H:%M:%S", localtime()) + " End of Game \n")for p in range(4):log.write(strftime("%H:%M:%S", localtime()) + " Player" + str(p + 1) + ":" + str(self.curmoney[p]) + " " + str(self.curtotal[p] - self.curmoney[p] + 15 * self.stockpledge[p]) + " -" + str(15 * self.stockpledge[p]) + " " + str(self.curtotal[p]) + "\n")print("Player" + str(p + 1) + ":" + str(self.curmoney[p]) + " " + str(self.curtotal[p] - self.curmoney[p] + 15 * self.stockpledge[p]) + " -" + str(15 * self.stockpledge[p]) + " " + str(self.curtotal[p]))return
















基于Python的马尼拉PC端桌游设计与实现相关推荐

  1. ESP32E基于Thonny——python框架,PC端进行局域网控制led亮灭

    ESP32基于Thonny--python框架,PC端进行局域网控制led亮灭 用中文讲,该如何实现这个功能呢? 1:成功连接wifi 2:能循环正常接收数据 3:判断接收的数据,使led亮灭 就3步 ...

  2. 一个基于 React 开发的PC端音乐App

    ?一个基于 React 开发的PC端音乐App. 同时支持 Mac 与 Windows 系统.下载地址 项目使用 electron 作为外壳,webpack 作为打包工具,核心技术包括 React + ...

  3. 大学计算机基础python学多久_基于Python 的“大学计算机基础”课程教学设计

    基于Python 的"大学计算机基础"课程教学设计 日期:2018-04-11 04:32 摘要 培养非计算机专业大学生的计算思维能力,在"大学计算机基础"课程 ...

  4. 【毕业设计_课程设计】基于python的微信公众平台机器人的设计与实现

    文章目录 0 项目说明 项目介绍 项目工程 0 项目说明 基于python的微信公众平台机器人的设计与实现 提示:适合用于课程设计或毕业设计,工作量达标,源码开放 项目介绍 1.NGINX做负载均衡, ...

  5. 基于Python的人机博弈象棋游戏的设计与实现

    源码获取:https://www.bilibili.com/video/BV1Ne4y1g7dC/ 基于Python的人机博弈象棋游戏的设计与实现

  6. 基于Python+Django+MYSQL的ERP管理系统的设计与实现

    基于Python+Django+MYSQL的ERP管理系统的设计与实现  源码获取:https://www.bilibili.com/video/BV1Ne4y1g7dC/ ERP管理系统是商业信息管 ...

  7. 基于Python的作业查重系统的设计和实现

    <基于Python的作业查重系统的设计和实现>该项目采用技术Python的django框架.mysql数据库,项目含有源码.论文.PPT.配套开发软件.软件安装教程.项目发布教程.核心代码 ...

  8. 基于Python的学生在线选课系统的设计和实现

    <基于Python的学生在线选课系统的设计和实现>该项目采用技术Python的django框架.mysql数据库 ,项目含有源码.论文.PPT.配套开发软件.软件安装教程.项目发布教程.核 ...

  9. 基于Python的水母吃鱼游戏的设计与实现

    源码获取:https://www.bilibili.com/video/BV1Ne4y1g7dC/ 基于Python的水母吃鱼游戏的设计与实现

最新文章

  1. 知乎上已获千赞,全网独家首发!
  2. 淘到了一个不错的TF卡读卡器
  3. Linux平台下C++编程
  4. 【车牌识别】+【模板匹配】基于智能交通的车牌识别系统
  5. Ubuntu中zabbix4.2配置shell脚本邮件报警
  6. CNN网络:MINST数据集的练习
  7. 创建新环境出现报错Collecting package metadata (current_repodata.json): failed.问题成功解决。
  8. version magic 不一致问题
  9. docker 容器访问宿主机服务
  10. matlab 三角函数 积化和差,三角函数积化和差与和差化积公式
  11. Excel教程 零基础到应用实操
  12. 卷三十一 汉纪二十三
  13. IOS 将文字写绘制成图片并转换为像素数据
  14. 热死了?总决赛从未出现1-3逆转 马刺已摸到总冠军
  15. php小写金额转大写金额
  16. CCNA初级课程,初识网络
  17. Excel 2007从入门到精通视频教程
  18. 【自我管理】精力,而非时间,是高效能的基础
  19. Verilator简介与使用
  20. [渝粤教育] 西南科技大学 电气控制与PLC 在线考试复习资料2021版(1)

热门文章

  1. ES 如何实现向量搜索【以图搜图/语义搜索】
  2. Federico Ferrari 和Ole Sigmund的高效3D拓扑优化程序
  3. 揭开MySQL索引神秘面纱
  4. 关于项目的可行性分析
  5. pki与其他人交流时的 机密性 完整性 身份验证 的整个过程
  6. matlab 眼睛的精确识别,整天对着电脑手机,如何保护好自己的眼睛?AI+眼镜了解一下!...
  7. 黑客挂马紧盯娃娃 儿童节育儿教育网站被挂马
  8. 看电子合同从“0”到“1”蜕变之路
  9. JAVA-制作飞机大战遇到的问题
  10. TTE系统容错设计(1) ——集中守护机制