打印ASCII艺术彼此相邻

时间:2017-10-30 11:41:33

标签: python-3.x ascii ascii-art

我试图为一个人创建一个Yahtzee游戏,使用随机数字作为骰子等等

我已经做到了,但我想要“漂亮”。游戏,所以我不想彼此相邻地输出五个随机整数,而是希望彼此相邻使用ASCII骰子。

这是我目前尝试测试此

def DiceFive():
    print ("-----")
    print ("|o o|")
    print ("| o |")
    print ("|o o|")
    print ("-----", end="")

def DiceSix():
    print ("-----")
    print ("|o o|")
    print ("|o o|")
    print ("|o o|")
    print ("-----", end="")

DiceSix()
DiceFive()

然而这输出很奇怪,

-----
|o o|
|o o|
|o o|
----------
|o o|
| o |
|o o|
-----

我的目标是让它看起来像这样

----- -----
|o o| |o o|
|o o| | o |
|o o| |o o|
----- -----

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

我将骰子放入包含骰子行(字符串)的元组列表中。然后你可以遍历骰子的高度(在这种情况下为5),所以你从索引0开始,然后遍历掷骰子并打印第一个骰子的第一行,然后是第二个骰子的第一行,等等。

DICE = [
    ("-----",
     "|   |",
     "| o |",
     "|   |",
     "-----",),
    ("-----",
     "|o  |",
     "|   |",
     "|  o|",
     "-----",),  # etc.
    ]


rolled_dice = (1, 2)

for i in range(5):  # 5 is the height of the die.
    for die in rolled_dice:
        # Now get the corresponding die in the DICE list
        # and print its first line, then the first line of
        # the next die and so on.
        print(DICE[die-1][i], end=' ')
    print()

答案 1 :(得分:2)

另一种方式:

five = """-----
|o o|
| o |
|o o|
-----""".split("\n")

six = """-----
|o o|
|o o|
|o o|
-----""".split("\n")


for row in zip(six, five):
    print(row[0] + " " + row[1])

输出:

----- -----
|o o| |o o|
|o o| | o |
|o o| |o o|
----- -----

答案 2 :(得分:0)

以下游戏改编自大约五年前发布的Python 2.5程序。它很旧,可能包含错误,但展示了一种在屏幕上有序显示卡片的可能性。第397-470行创建了可以显示的卡片。功能show_potshow_captured_cardsshow_playing_cardsshow_pot_before_play负责将卡片打印到屏幕上。

以下版本的游戏已经清理了一些,可能会更容易理解。游戏的主要逻辑是在{47}行开始的main函数中实现的。游戏的逻辑已被分解为函数,并且还添加了一些命名元组。使用下面显示的游戏中提供的各种示例,创建要在屏幕上显示的骰子应该不会太难实现。

#! /usr/bin/env python3
# http://code.activestate.com/recipes/578369-war-game-version-5/

"""Support module for array and matrix use.

This module provides two classes that emulate one and two
dimensional lists with fixed sizes but mutable internals."""

__all__ = ['Array', 'Matrix']
__version__ = '1.2'

import collections
import random


class Array(object):
    """array(length) -> new array
    array(length, value) -> initialized from value"""

    def __init__(self, length, value=None):
        """x.__init__(...) initializes x"""
        self.__data = list(range(length))
        for index in range(length):
            self.__data[index] = value

    def __repr__(self):
        """x.__repr__() <==> repr(x)"""
        return repr(self.__data)

    def __len__(self):
        """x.__len__() <==> len(x)"""
        return len(self.__data)

    def __getitem__(self, key):
        """x.__getitem__(y) <==> x[y]"""
        return self.__data[key]

    def __setitem__(self, key, value):
        """x.__setitem__(i, y) <==> x[i]=y"""
        self.__data[key] = value

    def __delitem__(self, key):
        """x.__delitem__(y) <==> del x[y]"""
        self.__data[key] = None

    def __iter__(self):
        """x.__iter__() <==> iter(x)"""
        return iter(self.__data)

    def __contains__(self, value):
        """x.__contains__(y) <==> y in x"""
        return value in self.__data


class Matrix(object):
    """matrix(rows, columns) -> new matrix
    matrix(rows, columns, value) -> initialized from value"""

    def __init__(self, rows, columns, value=None):
        """x.__init__(...) initializes x"""
        self.__data = Array(rows)
        for index in range(rows):
            self.__data[index] = Array(columns, value)

    def __repr__(self):
        """x.__repr__() <==> repr(x)"""
        return repr(self.__data)

    def __len__(self):
        """x.__len__() <==> len(x)"""
        return len(self.__data)

    def __getitem__(self, key):
        """x.__getitem__(y) <==> x[y]"""
        return self.__data[key]

    def __setitem__(self, key, value):
        """x.__setitem__(i, y) <==> x[i]=y"""
        self.__data[key] = Array(len(self.__data[key]), value)

    def __delitem__(self, key):
        """x.__delitem__(y) <==> del x[y]"""
        self.__data[key] = Array(len(self.__data[key]))

    def __iter__(self):
        """x.__iter__() <==> iter(x)"""
        return iter(self.__data)

    def __contains__(self, value):
        """x.__contains__(y) <==> y in x"""
        for item in self.__data:
            if value in item:
                return True
        return False


class Page(object):
    def __init__(self, rows, columns, value=None):
        self.__assert_type((int, rows), (int, columns))
        if value:
            self.__assert_type((str, value))
            self.__data = Matrix(rows, columns, value[0])
        else:
            self.__data = Matrix(rows, columns, ' ')
        self.__visible = True
        self.__x = 0
        self.__y = 0

    def __repr__(self):
        return repr(self.__data)

    def __str__(self):
        return '\n'.join([''.join(row) for row in self.__data])

    def size(self):
        """Return a tuple of matrix's size."""
        return len(self.__data), len(self.__data[0])

    def access(self, row, column, length=None):
        """Get a string of length from row and column."""
        self.__assert_type((int, row), (int, column))
        if length:
            self.__assert_type((int, length))
        else:
            length = 1
        string = ''
        for index in range(length):
            try:
                string += self.__data[row][column + index]
            except IndexError:
                pass
        return string

    def mutate(self, row, column, value):
        """Write a character or string where told."""
        self.__assert_type((int, row), (int, column), (str, value))
        for index in range(len(value)):
            try:
                self.__data[row][column + index] = value[index]
            except IndexError:
                pass
        return self

    def set_row(self, row, value=None):
        """Set or clear a row to one character."""
        self.__assert_type((int, row))
        if value:
            self.__assert_type((str, value))
            self.__data[row] = value[0]
        else:
            self.__data[row] = ' '
        return self

    def set_column(self, column, value=None):
        """Set or clear a column to one character."""
        self.__assert_type((int, column))
        if value:
            self.__assert_type((str, value))
        else:
            value = ' '
        for row in self.__data:
            row[column] = value[0]
        return self

    def visible(self, value=None):
        """Get or set visible."""
        if value is None:
            return self.__visible
        else:
            self.__assert_type((bool, value))
            self.__visible = value
            return self

    def x(self, value=None):
        """Get or set x."""
        if value is None:
            return self.__x
        else:
            self.__assert_type((int, value))
            self.__x = value
            return self

    def y(self, value=None):
        """Get or set y."""
        if value is None:
            return self.__y
        else:
            self.__assert_type((int, value))
            self.__y = value
            return self

    def project(self, value):
        """Copy value to self with offset."""
        for row in range(value.size()[0]):
            for column in range(value.size()[1]):
                try:
                    self.__data[value.y() + row][value.x() + column] = \
                        value.__data[row][column]
                except IndexError:
                    pass
        return self

    def page(self):
        """Casting statement."""
        return self

    def link(self, value):
        """Use and share value's __data."""
        if value.__class__ is Page:
            self.__data = value.__data
            return self
        else:
            raise ValueError

    def unlink(self):
        """Create a new matrix."""
        temp = Matrix(len(self.__data), len(self.__data[0]))
        # Copy all of the data to the new matrix.
        for row in range(len(self.__data)):
            for column in range(len(self.__data[0])):
                temp[row][column] = self.__data[row][column]
        # Finish the conversion.
        self.__data = temp
        # Allow more work to be done.
        return self

    @staticmethod
    def __assert_type(*tuples):
        for types, objects in tuples:
            if type(objects) is not types:
                raise TypeError


class Window(object):
    def __init__(self, height, width, border=None, background=None):
        self.__assert_type((int, height), (int, width))
        if border:
            self.__assert_type((str, border))
            self.__border = border[0]
        else:
            self.__border = ''
        if background:
            self.__assert_type((str, background))
            self.__background = background[0]
        else:
            self.__background = ' '
        self.__height = height
        self.__width = width
        self.__page = Page(0, 0)
        self.__list = list()
        self.__refresh()

    def __repr__(self):
        self.__refresh()
        return repr(self.__page)

    def __str__(self):
        self.__refresh()
        return str(self.__page)

    def __len__(self):
        return len(self.__list)

    def __getitem__(self, key):
        self.__assert_type((int, key))
        return self.__list[key]

    def __setitem__(self, key, value):
        self.__assert_type((int, key))
        if value.__class__ is Page or value.__class__ is Window:
            self.__list[key] = value
        else:
            raise ValueError

    def __delitem__(self, key):
        self.__assert_type((int, key))
        del self.__list[key]

    def __iter__(self):
        return iter(self.__list)

    def __contains__(self, value):
        """value in self"""
        return value in self.__list

    def __iadd__(self, value):
        """self += page || window"""
        if value.__class__ is Page or value.__class__ is Window:
            self.__list.append(value)
            # this line is required
            return self
        else:
            raise ValueError

    def __isub__(self, value):
        """self -= page || window"""
        while value in self.__list:
            self.__list.remove(value)
        # this line may be required
        return self

    def size(self, height=None, width=None):
        """This needs to be divided into two functions."""
        if height or width:
            if height:
                self.__assert_type((int, height))
                self.__height = height
            if width:
                self.__assert_type((int, width))
                self.__width = width
            return self
        return self.__height, self.__width

    def option(self, border=None, background=None):
        """This needs to be divided into two functions."""
        if border is not None or background is not None:
            if border is not None:
                self.__assert_type((str, border))
                if border:
                    self.__border = border[0]
                else:
                    self.__border = border
            if background is not None:
                self.__assert_type((str, background))
                if background:
                    self.__background = background[0]
                else:
                    self.__background = background
            return self
        return self.__border, self.__background

    def visible(self, value=None):
        """Get or set visible."""
        return self.__page.visible(value)

    def x(self, value=None):
        """Get or set x."""
        return self.__page.x(value)

    def y(self, value=None):
        """Get or set y."""
        return self.__page.y(value)

    def page(self):
        """This is like a casting statement."""
        self.__refresh()
        return self.__page

    def __refresh(self):
        temp = Page(self.__height, self.__width, self.__background) \
            .visible(self.__page.visible()).x(self.__page.x()).y(
            self.__page.y())
        self.__page = temp
        # Display Pages And Windows
        for item in self.__list:
            if item.visible():
                self.__page.project(item.page())
        # Create Borders
        if self.__border:
            self.__page.set_row(0, self.__border).set_row(self.__height - 1,
                                                          self.__border) \
                .set_column(0, self.__border).set_column(self.__width - 1,
                                                         self.__border)

    @staticmethod
    def __assert_type(*tuples):
        for types, objects in tuples:
            if type(objects) is not types:
                raise TypeError


def test_paw():
    it = Window(10, 10)
    print(it)
    print(it.option('#'))
    print(it.option(background='-'))
    it += Page(1, 1, '%').x(2).y(2)
    print(it)
    other = Page(2, 2, 'H')
    it += other.x(3).y(3)
    print(it)
    it -= other
    print(it)
    del it[0]
    print(it)
    other = Page(2, 2, '%')
    it += other.x(2).y(2)
    print(it)
    other_2 = Page(0, 0)
    it += other_2.y(5).x(2).link(other)
    print(it)
    other_2.mutate(0, 0, 'H')
    print(it)
    print(it.option('', ''))


card_0 = Page(5, 5)
card_0.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 0 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_1 = Page(5, 5)
card_1.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 1 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_2 = Page(5, 5)
card_2.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 2 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_3 = Page(5, 5)
card_3.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 3 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_4 = Page(5, 5)
card_4.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 4 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_5 = Page(5, 5)
card_5.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 5 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_6 = Page(5, 5)
card_6.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 6 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_7 = Page(5, 5)
card_7.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 7 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_8 = Page(5, 5)
card_8.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 8 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_9 = Page(5, 5)
card_9.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| 9 |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_10 = Page(5, 5)
card_10.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '|1 0|') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_A = Page(5, 5)
card_A.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| A |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_J = Page(5, 5)
card_J.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| J |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_Q = Page(5, 5)
card_Q.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| Q |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

card_K = Page(5, 5)
card_K.mutate(0, 0, '+---+') \
    .mutate(1, 0, '|   |').mutate(2, 0, '| K |') \
    .mutate(3, 0, '|   |').mutate(4, 0, '+---+')

CARD_LIST = [card_0, card_1, card_2, card_3, card_4, card_5, card_6, card_7,
             card_8, card_9]


def main():
    print('Welcome to WAR V5!\n')
    players = get_players()
    print()
    longest_name, names = get_names(players)
    deck = create_deck(players)
    hands = create_hands(deck, players)
    play_game_rounds(hands, longest_name, names, players)
    print('\n' * 50)
    display_scores(hands, names, players)
    for index in range(10):
        input(f'\nGAME OVER ... {9 - index}')


def display_scores(hands, names, players):
    for player_index, numeric_score in calculate_scores(hands, players):
        print(names[player_index], 'received', numeric_score, 'points.')


Score = collections.namedtuple('Score', 'player_index, numeric_score')


def calculate_scores(hands, players):
    scores = []
    for player in range(players):
        total = sum(hands[player].captured)
        scores.append(Score(player, total))
    scores.sort(key=lambda score: score.numeric_score)
    return scores


def play_game_rounds(hands, longest_name, names, players):
    for game_round in range(1, 11):
        table = []
        will_play = list(range(players))
        for turn in range(players):
            print('\n' * 50)
            play_one_person(game_round, hands, longest_name, names, table,
                            will_play)
        print('\n' * 50)
        show_pot(longest_name, names, table)
        distribute_pot(hands, table)
        summarize_captures(names, hands)
        input(f'\nEnd of Round {game_round}')


def show_pot(longest_name, names, table):
    table_window = Window(len(table) * 6, longest_name + 13)
    for index, (player_index, card) in enumerate(table):
        table_window += Page(1, len(names[player_index]) + 9) \
            .mutate(0, 0, names[player_index] + ' played') \
            .y(index * 6)
        table_window += Page(0, 0) \
            .link(CARD_LIST[card]) \
            .x(len(names[player_index]) + 8) \
            .y(index * 6)
    print(table_window)


def summarize_captures(names, hands):
    for index, hand in enumerate(hands):
        if hand.captured:
            print(names[index], 'has captured', len(hand.captured), 'cards.')


def distribute_pot(hands, table):
    high_card = max(item.card for item in table)
    hand_out = [player for player, card in table if card == high_card]
    while table:
        hands[random.choice(hand_out)].captured.append(table.pop(0).card)


def play_one_person(game_round, hands, longest_name, names, table,
                    will_play):
    now_play = will_play.pop(random.randrange(len(will_play)))
    print('Round', game_round)
    input(f"It is {names[now_play]}'s turn to play.\n")
    show_pot_before_play(longest_name, names, table)
    show_playing_cards(hands, now_play)
    show_captured_cards(hands, now_play)
    get_card_to_play(hands, now_play, table)


TableItem = collections.namedtuple('TableItem', 'player_index, card')


def get_card_to_play(hands, now_play, table):
    while True:
        try:
            card = int(input('What card do you want to play? '))
            if 0 <= card <= 9:
                try:
                    hands[now_play].playable.remove(card)
                except ValueError:
                    print('You do not have that card.')
                else:
                    table.append(TableItem(now_play, card))
                    break
            else:
                print('You must enter a value between 0 and 9.')
        except ValueError:
            print('You must enter a number.')


def show_captured_cards(hands, now_play):
    if hands[now_play].captured:
        hands[now_play].captured.sort()
        print('These are your captured cards:')
        capture_window = Window(7, len(hands[now_play].captured) * 6)
        for index, card in enumerate(hands[now_play].captured):
            capture_window += Page(0, 0) \
                .link(CARD_LIST[card]) \
                .x(index * 6 + 1) \
                .y(1)
        print(capture_window)


def show_playing_cards(hands, now_play):
    print('These are your playing cards:')
    playing_window = Window(7, len(hands[now_play].playable) * 6)
    for index, card in enumerate(hands[now_play].playable):
        playing_window += Page(0, 0) \
            .link(CARD_LIST[card]) \
            .x(index * 6 + 1) \
            .y(1)
    print(playing_window)


def show_pot_before_play(longest_name, names, table):
    if table:
        table_window = Window(len(table) * 6, longest_name + 13)
        for index, item in enumerate(table):
            table_window += Page(1, len(names[item.player_index]) + 9) \
                .mutate(0, 0, names[item.player_index] + ' played') \
                .y(index * 6)
            table_window += Page(0, 0) \
                .link(CARD_LIST[item.card]) \
                .x(len(names[item.player_index]) + 8) \
                .y(index * 6)
        print(table_window)
    else:
        print('There are no cards on the table.\n')


Hand = collections.namedtuple('Hand', 'playable, captured')


def create_hands(deck, players):
    hands = []
    random.seed()
    for player in range(players):
        hand = Hand([], [])
        for card in range(10):
            index = random.randrange(len(deck))
            hand.playable.append(deck.pop(index))
            hand.playable.sort()
        hands.append(hand)
    return hands


def create_deck(players):
    return [card for card in range(10) for _ in range(players)]


def get_names(players):
    names = [input(f'What is the name of player {name + 1}? ')
             for name in range(players)]
    return max(map(len, names)), names


def get_players():
    while True:
        try:
            players = int(input('How many players are there? '))
            if players > 1:
                return players
            print('There must be at least two players.')
        except ValueError:
            print('You must enter a number.')


if __name__ == '__main__':
    main()