7
\$\begingroup\$

Please Review and share suggestion :

https://github.com/prosenjitj/ConnectFour

enter image description here

Code:

import re
import string
import sys
PLAYING = "PLAYING"
WAITING = "WAITING"
WINNERX = "XXXX"
WINNERO = "OOOO"
## User Class
class User:
 state = ""
 name = ""
 def __init__(self,name, stateParam):
 self.name = name
 self.state = stateParam
 def userInfo(self):
 return self.name
 def getState(self):
 return self.state
 def setState(self, stateParam):
 self.state = stateParam
def printBoard(matrix):
 for num in range(1, 7):
 print(" "+ str(num) +" ", end = " ")
 print()
 for row in range(0, 6):
 for col in range(0, 6):
 print(" "+ str(matrix[row][col]) +" ", end = " ")
 print("")
def createMatrix(row, column) :
 mat = ["*"] * row
 for i in range(row):
 # mat[i] = ["" + str(i)] * column
 mat[i] = ["*"] * column
 return mat
def findMatrixMatched(matrix) :
 winFlg = False
 rowStrArr = []
 # get rows in String format
 for row in range(0, 6):
 str = ""
 for col in range(0, 6):
 str = str + matrix[row][col]
 rowStrArr.append(str)
 for rowStr in rowStrArr:
 # print("Row-" , rowStr)
 if WINNERX in rowStr or WINNERO in rowStr:
 winFlg = True
 break
 # get columns in String format
 colStrArr = []
 for col in range(0, 6):
 str = ""
 for row in range(0, 6):
 str = str + matrix[row][col]
 colStrArr.append(str)
 for colStr in colStrArr:
 # print("Col-" , colStr)
 if WINNERX in colStr or WINNERO in colStr :
 winFlg = True
 break
 # get diagonal match
 diagStrArr = [""] * 25
 for col in range(0, 6):
 diagNum = col
 for row in range(0, 6):
 if row + col > 5 :
 break
 if col == 0:
 diagStrArr[diagNum] = diagStrArr[diagNum] + matrix[row][row] # middle
 else :
 diagStrArr[diagNum] = diagStrArr[diagNum] + matrix[row][row + col] # upper
 diagStrArr[diagNum + 5] = diagStrArr[diagNum + 5] + matrix[row + col][row] # lower
 # get diagonal match
 for col in range(0, 6):
 diagNum = col + 12
 for row in range(0,6):
 rowId = 5-row
 # print(col , " ---- " , rowId, " ---- " , row)
 if rowId - col < 0 :
 break
 if col == 0:
 diagStrArr[diagNum] = diagStrArr[diagNum] + matrix[row][rowId] # middle
 else :
 diagStrArr[diagNum] = diagStrArr[diagNum] + matrix[row][rowId - col] # upper
 diagStrArr[diagNum + 5] = diagStrArr[diagNum + 5] + matrix[row + col][rowId] # lower
 for diagStr in diagStrArr:
 # print("Diag-" , diagStr)
 if WINNERX in diagStr or WINNERO in diagStr:
 winFlg = True
 break
 return winFlg
def appConnect():
 userA = User("A" , PLAYING)
 userB = User("B" , WAITING)
 matBoard = createMatrix(6,6)
 printBoard(matBoard)
 turn = 0
 while True:
 user = userA
 if turn % 2 == 0 :
 user = userA
 userA.setState(PLAYING)
 userB.setState(WAITING)
 else :
 user = userB
 userB.setState(PLAYING)
 userA.setState(WAITING)
 print(".................................................. ")
 print("Preference : ", user.userInfo() , " SEQ : ", str(turn + 1))
 print(".................................................. ")
 try:
 print( user.userInfo() , " turn >>>>>......................... ")
 color = str(input("Please select X or O > "))
 if color != 'X' and color != 'O' :
 print("Wrong Entry", color)
 continue
 colNum = int(input("Please Enter column Number >"))
 if colNum > 6 and colNum < 0:
 print("Wrong Entry -> Please Enter 1 - 5 :", colNum)
 continue
 colNum = colNum - 1; # column starting from 0
 for row in range(5, -1, -1):
 if matBoard[row][colNum] == "*" :
 matBoard[row][colNum] = color
 break;
 turn += 1
 except ValueError:
 print('Invalid Number !! Please try again')
 printBoard(matBoard)
 if findMatrixMatched(matBoard) :
 print(".................................................. ")
 print("User : ", user.userInfo() , " Win the Match by ", str(turn / 2) , " Steps")
 print(".................................................. ")
 break
 if turn >= 20:
 print("You have crossed maximum limits. Please start again.")
 break
if __name__ == '__main__':
 appConnect()
hjpotter92
8,9211 gold badge26 silver badges50 bronze badges
asked Feb 24, 2018 at 5:38
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

I've had a quick scan over the code, and a few things pop up:

The User class is overly complex for what you're actually doing with it (though you might have plans to use it more in future?)

You could get away with something simple like:

users = ['A', 'B']

and then toggle whose turn it is by just flipping between users[0] and users[1].

Now a nice trick is that False == 0 and True == 1, so users[False] is equivalent to users[0] which will be A (and users[True] will be B)

So your code could look something like:

turn = 0
while True:
 player = players[turn % 2 == 0] # Odd turns False, even turns True
 turn += 1

(If you keep the class, you could store the User instances in a list and get the same effect).

Your match strings (OOOO and XXXX) - it might be better to build these by doing:

win_count = 4
WINNERX = "X" * 4
WINNERO = "O" * 4

That way you can easily configure the game later to alter the win condition by changing the variable.

Alternatively... you can not worry about maintaining WINNERX and WINNERO at all - and just test if the string contains the same character n (4) times:

# Replace
if WINNERX in rowStr or WINNERO in rowStr:
# with
if rowStr == rowStr[0] * win_count:

The same string multiplier could be used in other places for neatness - such as the `print(".....") lines.

You might also want to set board size variables and use them in the range calls that set up the board, colNum etc, to allow a different board size easily.

Your use of winFlag/break could be removed - since you only use it to then return winFlag. Why not just do return True or return False in place of setting/breaking/returning?

if colNum > 6 and colNum < 0 - this should be or not and.

imports - you're importing several libraries you're not using - re, string and `sys.

You might want to consider using format for some of the print statements joining strings. If nothing else, this would remove the need to cast int to str in print statements.

str = "" - str is a builtin method so shouldn't be overridden - choose a different variable name.

Really minor, but turn >= 20 could be turn == 20 - there's no way to get to 21 without first carrying out that test.

Finally, consider running the code through pylint and pycodestyle - there are a number of minor layout and formatting issues that would benefit from fixing.

Hopefully that's enough ideas to be getting started with!

answered Feb 24, 2018 at 9:49
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.