Python Forum
Python not correctly choosing numbers for my game.
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python not correctly choosing numbers for my game.
#1
So there is this game, the name of it starts with an S, I don't know how to spell it. The game is a number game where you have so many rows and columns of numbers. Each column and row only has one of each number, and you have to solve it by filling in all the numbers properly. I am trying to re-create that game but I just can't get the number choosing part to work right. In my game there are buttons. Each button is on a column and row 1-9. I need the program to choose numbers for each of the buttons while making sure each column and row has only one of each number 1-9. I can't seem to get this to work properly. I am able to get the program to choose numbers for each button, but there are some numbers that are getting numbers that have already been taken by another button in that column or row. The way I am attempting to do this is by giving each button a column and row and placing them into a list. The program then uses a for loop to get each button then another for loop to check for all the buttons in the selected buttion's column and row. It then gets the value of the buttons and creates a list of available options. Then I have it select a random number from the list to give to the selected button and it will then reset the list and move on to the next button. But some how it does not seem to be working properly. Idon't know what to do. I have created some code that allows me to check if the buttons are in their proper columns and rows and they are all placed properly, so it does not look to be a problem with placement the choosing code just does not seem to be working properly.

def Choose(self):
        #choose numbers.
        for b in self.nb:
            self.n1 = True#n1-n9 are used to create the list of possible numbers.
            self.n2 = True
            self.n3 = True
            self.n4 = True
            self.n5 = True
            self.n6 = True
            self.n7 = True
            self.n8 = True
            self.n9 = True
            nlist = []#list used to get possible numbers.
            n = 0 #used to get how many numbers there are to choose from. If only one, the button gets what ever number is in the list.
            if b.value == 0:
                for i in self.nb:
                    if i.r == b.r:
                        self.Clist(i)#Clist changes n1-n9 to false if number is already in column or row.
                    if i.c == b.c:
                        self.Clist(i)
                if self.n1 == True:#Gets what numbers are true and adds then to nlist.
                    nlist.append('1')
                if self.n2 == True:
                    nlist.append('2')
                if self.n3 == True:
                    nlist.append('3')
                if self.n4 == True:
                    nlist.append('4')
                if self.n5 == True:
                    nlist.append('5')
                if self.n6 == True:
                    nlist.append('6')
                if self.n7 == True:
                    nlist.append('7')
                if self.n8 == True:
                    nlist.append('8')
                if self.n9 == True:
                    nlist.append('9')
                for item in nlist:#checks how many items are in nlist.
                    n += 1
                if n == 1:
                    N = nlist[0]
                if n > 1:
                    N = random.choice(nlist)
                if N == '1':#Get number and set the value of the current button to the number.
                    b.value = 1
                if N == '2':
                    b.value = 2
                if N == '3':
                    b.value = 3
                if N == '4':
                    b.value = 4
                if N == '5':
                    b.value = 5
                if N == '6':
                    b.value = 6
                if N == '7':
                    b.value = 7
                if N == '8':
                    b.value = 8
                if N == '9':
                    b.value = 9
def Clist(self,i):
        if i.value == 1:
            self.n1 = False
        if i.value == 2:
            self.n2 = False
        if i.value == 3:
            self.n3 = False
        if i.value == 4:
            self.n4 = False
        if i.value == 5:
            self.n5 = False
        if i.value == 6:
            self.n6 = False
        if i.value == 7:
            self.n7 = False
        if i.value == 8:
            self.n8 = False
        if i.value == 9:
            self.n9 = False


I just don't understand what is going on. I can't see anything wrong. Does anyone have any ideas of what I should to to make this work?
Reply
#2
Quote:Python not correctly choosing numbers for my game.
more likely:
Python code not correctly choosing numbers for my game.
What does the same of game sound like ... take a stab at it, so the actual rules can be found.
Reply
#3
Sound like he trying to make Sudoku. 9 rows and 9 columns. Split into 3x3 grid.

1. I don't see enough code to suggest a fix.

2. Don't know GUI you are using? tkinter, pygame, wxpython, pyQt.

3. You need to learn to use containers. List or Dicts instead of making variables n1 to n9.
example. Your code simplified.
def Choose(self):
    for b in self.nb:
        possible = []
        for n in range(10):
            possible.append(True)

        if b.value == 0:
            for i in self.nb:
                if i.r == b.r:
                    possible[i.value] = False
                elif i.c == b.c:
                    possible[i.value] = False

            nlist = []
            for n in range(1,10):
                if possible[n]:
                    nlist.append(n)

            if len(nlist) == 1:
                b.value = nlist[0]
            elif len(nlist) > 1:
                b.value = random.choice(nlist)
99 percent of computer problems exists between chair and keyboard.
Reply
#4
Another solution:
numbers_used = [0, 0, 0, 0, 0, 0, 0, 0, 0]
slots_used = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

def get_a_number(message, min, max):
    number = ''
    while True:
        while not number.isdecimal():
            number = input(message)
        number = int(number)
        if number < min or number > max:
            print('Number must be between {} and {}'.format(min, max))
            continue
        break
    return(int(number))

def pick_a_number():
    index = 0
    row = 0
    column = 0
    while True:
        row = get_a_number('Please enter row: ', 1, 3)
        column = get_a_number('Please enter column: ', 1, 3)
        if slots_used[row - 1][column - 1]:
            print('Row: {}, Column: {} is already occupied'.format(row, column))
            continue
        number = get_a_number ('Please pick a number between 1 and 9: ', 1, 9)
        if numbers_used[number - 1]:
            print('Sorry, that number has already been used')
            continue
        break
    print(f'row: {row}, column: {column} number: {number}')
    numbers_used[number - 1] = 1
    slots_used[row-1][column-1] = 1
    return number, row, column

def testit():
    count = 0
    while True:
        number, row, column = pick_a_number()
        print('Selected: {} in row: {}, column: {}'.format(number, row, column))
        count += 1
        if count == 9:
            break

if __name__ == '__main__':
    testit()
Reply
#5
Yes I am trying to make Sudoku. I am using PyQt. I took your code and put it in place of my code but I am still having the same problems. I have a 9 by 9 grid with blocks of 3 by 3. Most of the numbers get chosen just fine but there are some that are not and for some reason when I put your code in I now get problems of some of the buttons not even getting a number.
Reply
#6
1. still not seeing enough code.

example
import random
EMPTY = '-'

class Sudoku:
    def __init__(self):
        # shorthand
        # self.board = [[EMPTY for y in range(9)] for x in range(9)]
        # long
        self.board = []
        for y in range(9):
            row = []
            for x in range(9):
                row.append(EMPTY)
            self.board.append(row)

    def choose(self, x, y):
        if self.board[x][y] == EMPTY:
            possible = [True for n in range(10)]
            for i in range(9):
                if self.board[x][i] != EMPTY:
                    possible[self.board[x][i]] = False
                elif self.board[i][y] != EMPTY:
                    possible[self.board[i][y]] = False

            grid = int(x / 3) * 3, int(y / 3) * 3
            for i in range(grid[0], grid[0] + 3):
                for j in range(grid[1], grid[1] + 3):
                    if self.board[i][j] != EMPTY:
                        possible[self.board[i][j]] = False

            nlist = []
            for n in range(1, 10):
                if possible[n]:
                    nlist.append(n)

            self.board[x][y] = random.choice(nlist)

    def __repr__(self):
        r = ''
        for enum, row in enumerate(self.board):
            r += '{0} {1} {2}   {3} {4} {5}   {6} {7} {8}\n'.format(*row)
            if enum > 1 and (enum + 1) % 3 == 0:
                r += '\n'
        return r

sud = Sudoku()
for x in range(40):
    sud.choose(random.randint(0,8), random.randint(0,8))
print(sud)
99 percent of computer problems exists between chair and keyboard.
Reply
#7
Here is a modified version of my code I replaced the buttons with QLabels. It creates the window and places all the buttons on the screen. Press the 'N' key to choose the numbers.
from PyQt4 import QtCore, QtGui
import sys
import random

class Main(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.resize(519, 594)
        self.setMouseTracking(True)
        self.font = QtGui.QFont()
        self.font.setPointSize(22)
        self.nb = []
        self.createB()
            
    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_N:
            self.newGame()

    def MakeL(self,x,y,r,c):
        L = QtGui.QLabel(self)
        L.setGeometry(QtCore.QRect(x, y, 25, 25))
        L.setFont(self.font)
        L.setText('N')
        L.x = x
        L.y = y
        L.r = r
        L.c = c
        L.value = 0
        self.nb.append(L)

    def createB(self):
        x = 30
        y = 30
        c = 1
        r = 1
        for i in range(81):
            self.MakeL(x,y,r,c)
            if x == 130:
                x += 10
            if x == 290:
                x += 10
            if x == 450:
                x = -20
                y += 50
                r += 1
            if y == 180:
                y += 10
            if y == 340:
                y += 10
            x += 50
            c += 1
            if c == 10:
                c = 1
            
    def newGame(self):
        for b in self.nb:
            b.value = 0
            b.setText('N')
        self.Choose()

    def Choose(self):
        for b in self.nb:
            possible = []
            for n in range(10):
                possible.append(True)
 
            if b.value == 0:
                for i in self.nb:
                    if i.r == b.r:
                        possible[i.value] = False
                    elif i.c == b.c:
                        possible[i.value] = False
 
                nlist = []
                for n in range(1,10):
                    if possible[n]:
                        nlist.append(n)
 
                if len(nlist) == 1:
                    b.value = nlist[0]
                elif len(nlist) > 1:
                    b.value = random.choice(nlist)
                s = str(b.value)
                b.setText(s)

app = QtGui.QApplication(sys.argv)
win = Main()
win.show()
sys.exit(app.exec_())
The only other possible fix that I have come up with is I would have to manually create ten to twenty puzzles and have it randomly choose from one of then to use.
Reply
#8
You going have to go deeper into math to create a full puzzle or create them manually.

example a test. Haven't block 3x3 match within blocks yet.
The zeros had no choices to pick from.
import sys
import random
from PyQt4 import QtCore, QtGui

class Main(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.resize(519, 594)
        self.setMouseTracking(True)
        self.font = QtGui.QFont()
        self.font.setPointSize(22)
        self.make_labels()
        self.create()

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_N:
            self.create()

    def make_labels(self):
        self.labels = []
        self.values = []
        for y in range(9):
            l_row = []
            v_row = []
            yy = 50 * y + 30 + int(y / 3) * 10
            for x in range(9):
                label = QtGui.QLabel(self)
                xx = 50 * x + 30 + int(x / 3) * 10
                label.setGeometry(QtCore.QRect(xx, yy, 25, 25))
                label.setFont(self.font)
                label.setText('N')
                l_row.append(label)
                v_row.append(0)

            self.labels.append(l_row)
            self.values.append(v_row)

    def create(self):
        possible_across = []
        possible_down = []
        for y in range(9):
            possible_across.append([True for i in range(10)])
            possible_down.append([True for i in range(10)])

        for y in range(9):
            for x in range(9):
                rlist = []
                for n in range(1, 10):
                    if possible_across[y][n] and possible_down[x][n]:
                        rlist.append(n)

                if len(rlist) > 1:
                    rnd = random.choice(rlist)
                else:
                    try:
                        rnd = rlist[0]
                    except:
                        rnd = 0

                possible_across[y][rnd] = False
                possible_down[x][rnd] = False
                self.values[y][x] = rnd
                self.labels[y][x].setText(str(rnd))

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = Main()
    win.show()
    app.exec_()

example a test. Added block checks. Zeros appear more often.
import sys
import random
from PyQt4 import QtCore, QtGui

class Main(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.resize(519, 594)
        self.setMouseTracking(True)
        self.font = QtGui.QFont()
        self.font.setPointSize(22)
        self.make_labels()
        self.create()

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_N:
            self.create()

    def make_labels(self):
        self.labels = []
        self.values = []
        for y in range(9):
            l_row = []
            v_row = []
            yy = 50 * y + 30 + int(y / 3) * 10
            for x in range(9):
                label = QtGui.QLabel(self)
                xx = 50 * x + 30 + int(x / 3) * 10
                label.setGeometry(QtCore.QRect(xx, yy, 25, 25))
                label.setFont(self.font)
                label.setText('N')
                l_row.append(label)
                v_row.append(0)

            self.labels.append(l_row)
            self.values.append(v_row)

    def create(self):
        possible_across = []
        possible_block = []
        possible_down = []
        for y in range(9):
            possible_across.append([True for i in range(10)])
            possible_block.append([True for i in range(10)])
            possible_down.append([True for i in range(10)])

        for y in range(9):
            for x in range(9):
                rlist = []
                zone = int(y / 3) * 3 + int(x / 3)
                for n in range(1, 10):
                    if possible_across[y][n] and possible_down[x][n] and possible_block[zone][n]:
                        rlist.append(n)

                if len(rlist) > 1:
                    rnd = random.choice(rlist)
                else:
                    try:
                        rnd = rlist[0]
                    except:
                        rnd = 0

                possible_block[zone][rnd] = False
                possible_across[y][rnd] = False
                possible_down[x][rnd] = False
                self.values[y][x] = rnd
                self.labels[y][x].setText(str(rnd))

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = Main()
    win.show()
    app.exec_()
99 percent of computer problems exists between chair and keyboard.
Reply
#9
Okay, well I think I will try some more stuff with it. Maybe I can get to work. Thank you.
Reply
#10
did you try my post # 4?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  From python game in terminal to a website game using bottle Njanez 0 3,871 Aug-13-2021, 01:11 PM
Last Post: Njanez

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020