简体   繁体   English

Catan:使用Python 3.x将骰子卷与拥有的资源相关联

[英]Catan: Correlating Dice Rolls to Owned Resources Using Python 3.x

I would like to enter the number rolled on two six-sided dice and print out only the owned resources associated with that number. 我想输入滚动在两个六面骰子上的数字,并仅打印出与该数字相关的拥有资源。

In the game Settlers of Catan, up to three assets (settlements and cities) can be built on any one of 19 hexagonal resource grids corresponding to the numbers rolled using two six-sided die (2-12). 在游戏《卡坦的定居者》中,最多可以在19个六边形资源网格中的任何一个上建立三个资产(定居点和城市),这些资源网格对应于使用两个六面骰子(2-12)滚动的数字。 The numbers 2 and 12 are represented once on the gameboard, while 3-11 are represented twice. 数字2和12在游戏板上代表一次,而数字3-11在游戏板上代表两次。

Currently, my program allows the operator to update the R[num] matrices to reflect the Blue/Red/Orange/White players' ownership of the stated resource once a settlement (value=1 resource, default) or city (value=2 resource) has been built on that particular hexadecimal grid. 当前,我的程序允许操作员更新R [num]矩阵,以反映定居点(值= 1,默认值)或城市(值= 2,资源)的蓝/红/橙/白玩家对指定资源的所有权)已建立在该特定的十六进制网格上。

#! Python 3.x
R2 = [ ['color', '1', 'sheep'], ['color', '1', 'sheep'], ['color', '1', 'sheep'] ]
R3 = [ ['color', '1', 'wood'], ['color', '1', 'wood'], ['color', '1', 'wood'],
['color', '1', 'stone'], ['color', '1', 'stone'], ['color', '1', 'stone'] ]
R4 = [ ['color', '1', 'hay'], ['color', '1', 'hay'], ['color', '1', 'hay'],
['color', '1', 'sheep'], ['color', '1', 'sheep'], ['color', '1', 'sheep'] ]
R5 = [ ['color', '1', 'brick'], ['color', '1', 'brick'], ['color', '1', 'brick'],
['color', '1', 'sheep'], ['color', '1', 'sheep'], ['color', '1', 'sheep'] ]
R6 = [ ['color', '1', 'hay'], ['color', '1', 'hay'], ['color', '1', 'hay'],
['color', '1', 'brick'], ['color', '1', 'brick'], ['color', '1', 'brick'] ]
R7 = ['You\'ve been robbed!']
R8 = [ ['color', '1', 'wood'], ['color', '1', 'wood'], ['color', '1', 'wood'],
['color', '1', 'stone'], ['color', '1', 'stone'], ['color', '1', 'stone'] ]
R9 = [ ['color', '1', 'hay'], ['color', '1', 'hay'], ['color', '1', 'hay'],
['color', '1', 'wood'], ['color', '1', 'wood'], ['color', '1', 'wood'] ]
R10 = [ ['color', '1', 'brick'], ['color', '1', 'brick'], ['color', '1', 'brick'],
['color', '1', 'stone'], ['color', '1', 'stone'], ['color', '1', 'stone'] ]
R11 = [ ['color', '1', 'wood'], ['color', '1', 'wood'], ['color', '1', 'wood'],
['color', '1', 'sheep'], ['color', '1', 'sheep'], ['color', '1', 'sheep'] ]
R12 = [ ['color', '1', 'hay'], ['color', '1', 'hay'], ['color', '1', 'hay'] ]

dict = {2:R2, 3:R3, 4:R4, 5:R5, 6:R6, 7:R7, 8:R8, 9:R9, 10:R10, 11:R11, 12:R12}

def main():
    while True:
        while True:
            try:
                roll = input('Input rolled number or enter zero(0) to quit: ')
                roll = int(roll)
                break
            except ValueError:
                print('\'', roll, '\' is not a valid number! Please try again.\n')
        if roll == 0: break 
        elif roll < 2:
            print('You entered:', roll, '\n\n' 'Please enter a number between 2 and 12.')
        elif roll > 12:
            print('You entered:', roll, '\n\n' 'Please enter a number between 2 and 12.')
        else:
            print('You entered:', roll,'\n')
            for x in dict[roll]:
                print(x)
        print('\n')
if __name__ == '__main__':
    main()

What I would like this program to do is only display the owned resources for a given roll of the dice. 我希望该程序仅显示给定骰子所拥有的资源。

For example*, if the Blue player owned one settlement on the #2 resource (sheep), and the Red player owned one city on the same resource, then when a 2 was rolled, the program would display something like: 例如*,如果蓝色玩家在#2资源(绵羊)上拥有一个定居点,而红色玩家在同一资源上拥有一个城市,则当滚动2时,程序将显示如下内容:

Blue, 1, sheep 蓝色,1,绵羊

Red, 2, sheep 红色,2,绵羊

Thank you for taking the time to consider this matter. 感谢您抽出宝贵时间考虑此事。

*R2=[['Blue', '1', 'sheep'], ['Red', '2', 'sheep'], ['color', '1', 'sheep']] * R2 = [['蓝色','1','绵羊'],['红色','2','绵羊'],['颜色','1','绵羊']]

As I understand it, you want to pretty-print resource lists only if the resources are owned by one of the players. 据我了解,仅当资源由播放器之一拥有时,您才需要漂亮地打印资源列表。

The simplest way to do this is to put the players' names into a collection, and check the team name in the resource list for that name when processing the dice roll. 最简单的方法是将玩家的姓名放入集合中,并在处理掷骰子时检查资源列表中的球队名称。

As the number of team names is small, we can just use a tuple or list to hold them. 由于团队名称的数量很少,我们只能使用tuplelist来保存它们。 If the number of names was large then a set or frozenset would be a better choice, because finding items in sequences like tuples or lists takes time in proportion to their length, but for sets lookup time is not affected by the number of elements. 如果名称的数量很大,则最好使用setfrozenset set ,因为在像元组或列表这样的序列中查找项目所花费的时间与其长度成比例,但是对于集合,查找时间不受元素数量的影响。

TEAMS = ("Blue", "Orange", "Red", "White")

To pretty-print the lists, use the join method of strings to make a string consisting of each part of the resource, separated by a comma and a space. 要漂亮地打印列表,请使用字符串的join方法制作一个字符串,该字符串由资源的每个部分组成,并用逗号和空格分隔。

        for color, count, resource in dict[roll]:
            if color in TEAMS:
                pretty = ", ".join((color, count, resource))
                print(pretty)

Expanding the resource list into color, count, resource is called unpacking, and it helps make the code more readable. 将资源列表扩展为color, count, resource称为拆包,它有助于使代码更具可读性。 Without unpacking you would write 如果不打开包装,您会写

        for x in dict[roll]:
            if x[0] in TEAMS:
                pretty = ", ".join(x)
                print(pretty)

This is slightly trickier to read, because you need to remember the structure of x , rather than it being clear from the variable names. 读起来有点棘手,因为您需要记住x的结构,而不是从变量名中清楚地知道它。

Speaking of variable names, try to not to overwrite the names of builtin functions, like dict , in your code: it will confuse readers of your code, possibly including yourself. 说到变量名,请尽量不要在代码中覆盖内置函数的名称,例如dict :它将使您的代码读者(可能包括您自己)感到困惑。

The practice of selecting items from a collection is known as filtering , and Python provides a builtin function - filter to make this easier to code. 从集合中选择项目的做法称为过滤 ,Python提供了一个内置函数- filter ,使编码更容易。 filter accepts a function that returns True for selectable items and False for others, and the collection that you want to filter. filter接受一个函数,该函数为可选项返回True,为其他项返回False,以及要过滤的集合。 Using, filter , the code would look like this: 使用filter ,代码如下所示:

def selecter(status):
    color, item, team = status
    return color in TEAMS

    for status in filter(selecter, dict[roll]):
        pretty = ", ".join(status)
        print(pretty)

For simple functions like selecter , it's common to use a lambda instead; 对于这样简单的功能selecter ,这是通常使用lambda代替; a lambda is a limited kind of function that's useful in situations where you don't need to reuse the function, and so don't want it to clutter up your code. lambda是一种有限的函数,在不需要重用该函数的情况下很有用,因此您不希望它使代码混乱。

Using a lambda, the code would look like this: 使用lambda,代码如下所示:

        # You can't unpack a tuple in a lambda :-(
        for status in filter(lambda x: x[0] in TEAMS, dict[roll]):
            pretty = ", ".join(status)
            print(pretty)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM