Doubt print game list of old Python

Asked

Viewed 101 times

-2

I’m developing the old game, which is still in the beginning. I’m having trouble trying to print the first line of the list. When I print the list, it’s always empty.

There could be two mistakes:

  • or I’m not correctly adding the symbol to the list;
  • or the print is wrong.

As you can see from the image I posted, line 1 doesn’t print anything, but line 2 does.

Obs: the function player2 I haven’t updated yet, so it’s different.

import numpy as np

positions = [0,1,2]
velha = [ ["","",""] , ["","",""] , ["","",""] ]

def player1():
    global velha

    print(velha[0])
    print(velha[1])
    print(velha[2])

    linha = int(input("Escolha uma linha: "))
    coluna = int(input("Escolha uma linha: "))
    if linha and coluna in positions:
     if velha[linha][coluna] == "":
        try:
            velha[linha][coluna] = 'X'
        except:
            print("essa posição está ocupada")

    else:
        print("Por favor digite uma posição válida")
        player1()

def player2():
    global velha
    print(velha[0])
    print(velha[1])
    print(velha[2])
    try:
        linha = int(input("Escolha uma linha: "))
        coluna = int(input("Escolha uma linha: "))
        if linha and coluna in positions:
            try:
                if velha[linha][coluna] == " ":
                    velha[linha][coluna] = 'O'
            except:
                print("essa posição está ocupada")

    except:
        print("Por favor digite uma posição válida")
        player2()

while True:
    player1()
    player2()

inserir a descrição da imagem aqui

  • 1

    I didn’t stop to look at all the code, but in any case, if you want to have old game implementations here and here

  • vlw man, thanks. I took a look here!

2 answers

1

Your mistake is here if linha and coluna in positions: Python will not scan the 2x positions column because it used the operator and I know that in the head it makes more sense to think like an "E". But Python will check if row and column are True and will continue. So much so that if you put a higher value than what is in the position it will continue and give an Indexerror:

In that case you have to do 2 checks

if linha in positions and coluna in positions:
  • 1

    Vlw Rodrigo, thank you very much!!

1

The first step to understanding your algorithm is to put it to work. For this I corrected some improper assignments and then rewrote comparison:

if linha and coluna in positions:

for:

if all(p in positions for p in {linha, coluna}):

where the function built in all(), returning True only if all element of an eternal are True, tests all the element of generating expression if for element of set {linha, coluna} is contained in positions.

So I could run this code:

positions = range(3)  #Range ao invés de lista
velha = [["","",""] for p in positions] # List comprehension ao invés do literal

def player1():
    global velha

    print(velha[0])
    print(velha[1])
    print(velha[2])

    linha = int(input("Escolha uma linha: "))
    coluna = int(input("Escolha uma coluna: "))
    
    # Se todo elemento p contido no set {linha, coluna} estiver em positions... 
    if all(p in positions for p in {linha, coluna}):
     if velha[linha][coluna] == "":
        try:
            velha[linha][coluna] = 'X'
        except:
            print("essa posição está ocupada")

    else:
        print("Por favor digite uma posição válida")
        player1()

def player2():
    global velha
    print(velha[0])
    print(velha[1])
    print(velha[2])
    try:
        linha = int(input("Escolha uma linha: "))
        coluna = int(input("Escolha uma coluna: "))
        # Se todo elemento p contido no set {linha, coluna} estiver em positions...
        if all(p in positions for p in {linha, coluna}):
            try:
                if velha[linha][coluna] == "": #Troca de " " para ""
                    velha[linha][coluna] = 'O'
            except:
                print("essa posição está ocupada")

    except:
        print("Por favor digite uma posição válida")
        player2()

while True:
    print('Jogador X...')  #Mostra de quem é a vez.
    player1()
    print('Jogador O...')  #Mostra de quem é a vez.
    player2()

After understanding the algorithm I made some changes, removing the redundancy, removing the treatments from malescessary exceptions, breaking the code into more specialized actions and creating a function jogada() that makes the moves of both players, the function vencedor() who tests the board for a winner and a closure flag() which is a predictable biestade function, at each reading it alternates the value between 0 and 1 and initial value is 0, used to iterate over string characters "XO" aiming to alternate the players each jogada():

positions = range(3)  #Define a dimensões do tabuleiro.

#Essa função apenas exibe o tabuleiro.
def exibir_tabuleiro(tabuleiro):
    for p in positions: print(tabuleiro[p])
    
#Essa função apenas valida se a entrada s é um dos valores no iteravel p.
def validar_entrada(s, p):
    return s.isdigit() and (int(s) in p)

#Pede para o usuário entrar com um valor de acordo com o rotulo.
def selecionar(rotulo):
    while True:
      e = input(f"Escolha uma {rotulo}: ")
      if not validar_entrada(e, positions):
          print(f"Erro: {rotulo} inválida!{tuple(positions)}")
          continue
      return int(e)
    
#Retorna a célula (linha, coluna) selecionada pelo usuário.
def selecionar_celula():
    return tuple(selecionar(r) for r in ["linha", "coluna"]) 
    
#Informa qual o jogador da vez.
def informar_jogador(s):
    print(f"Jogador {s}...")
    
#Verifica se uma jogada é ou não válida.
def validar_jogada(l, c, t):
    return all(p in positions for p in {l, c}) and (t[l][c] == "")
   
#Efetua uma jogada para o jogador no tabuleiro. O comportamento do interpretador é iniciar o default apenas na primeira chamada da função.
def jogada(jogador, tabuleiro=[[""]*len(positions) for p in positions]):
    valida = False
    exibir_tabuleiro(tabuleiro)
    while not valida:
        informar_jogador(jogador)
        linha, coluna = selecionar_celula()
        valida = validar_jogada(linha, coluna, tabuleiro)
        if valida:
            tabuleiro[linha][coluna] = jogador
        else:
            print(f"{'-'*3} A posição {(linha, coluna)} já está ocupada, jogue novamente {'-'*3}")
            
    return tabuleiro
    
#Testa um vetor para saber se tem todos os caracteres iguais e se sim retorna o caractere senão retorna None 
def vetor_vencedor(v):
    if v.count(v[0]) == len(v):
        if v[0] != "" : 
            #print(f"Vencedor jogador {v[0]}.")
            return v[0]
    
#Testa cada uma das linhas do tabuleiro para saber se tem todos os caracteres iguais e se sim retorna o caractere senão retorna None    
def verificar_linhas(tabuleiro):
    for linha in tabuleiro:
        if vetor_vencedor(linha):
            return linha[0]

#Testa cada uma das colunas do tabuleiro para saber se tem todos os caracteres iguais e se sim retorna o caractere senão retorna None 
def verificar_colunas(tabuleiro):
    for c in positions:
        coluna = [linha[c] for linha in tabuleiro]
        if vetor_vencedor(coluna):
            return coluna[0]
    
#Testa a diagonal principal do tabuleiro para saber se tem todos os caracteres iguais e se sim retorna o caractere senão retorna None    
def verificar_diagonal_principal(tabuleiro):
    diagonal = [tabuleiro[p][p] for p in positions]
    if vetor_vencedor(diagonal):
        return diagonal[0]

#Testa a diagonal secundária do tabuleiro para saber se tem todos os caracteres iguais e se sim retorna o caractere senão retorna None
def verificar_diagonal_secundaria(tabuleiro):
    diagonal = [tabuleiro[positions[-1] - p][p] for p in positions]
    if vetor_vencedor(diagonal):
        return diagonal[0]
        
#Testa o a procura de um vencedor, se houver um vencedor o retorna senão retorna None.
def vencedor(tabuleiro):
    v = (verificar_linhas(tabuleiro) or 
         verificar_colunas(tabuleiro) or
         verificar_diagonal_principal(tabuleiro) or
         verificar_diagonal_secundaria(tabuleiro))
    if v: 
        print(f"{'-'*10} Jogo encerrado {'-'*10}")
        print(f"Vencedor jogador {v}.")
        exibir_tabuleiro(tabuleiro)
        return v
  
#Closure biestado, a cada execução da função seu retorno alterna entre 0 e 1.
def flag():
    f = True
    def __flag():
        nonlocal f
        f = not f
        return int(f)
    return __flag
    
flag = flag() #Obtém o closure

while not vencedor(jogada("XO"[flag()])):
    print(f"{'-'*10} Jogada encerrada {'-'*10}")
  • Hi Augusto, thank you so much! Helped me a lot!

  • Augusto, your code is kind of advanced for me. It’s hard to read and understand. hahaha, but reading more advanced code is that we progress.

  • @Pedroivo, is having trouble?

  • I didn’t quite understand this idea of "label". didn’t understand in the validar_move function, what and( t[l][c] == "" does. For now that’s it, then I’ll read more calmly and send other questions.

  • The data collection is the same for both row and column, only changes the label and the original algorithm asks the player to enter first with the row and then with the column.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.