importFoundation// possible winning moves in the form of [ [deltaRow, deltaCol] ]letacrossWinCords=[[0,0],[0,1],[0,2],[0,3]]letvertWinCords=[[0,0],[-1,0],[-2,0],[-3,0]]letdiagUpWinCords=[[0,0],[-1,1],[-2,2],[-3,3]]letdiagDownWinCords=[[0,0],[1,1],[2,2],[3,3]]letred=Character("R")letyellow=Character("Y")letblank=Character("")// helper function to initalize a gameboard with all blanks.funcinitBoard()->[[Character]]{letnewRow=[Character](repeating:blank,count:7)letnewBoard=[[Character]](repeating:newRow,count:6)returnnewBoard}// helper function to neatly print out the boardfuncprintBoard(_board:[[Character]]){print("Row A B C D E F G")forindexin0..<board.count{print("",index,"",board[index])}}// helper function, checks to make sure its within bounds of the game board.funcvalidMove(_row:Int,_col:Int)->Bool{if(row>=0&&col>=0)&&(row<=5&&col<=6){returntrue}returnfalse}functestForWin(_board:[[Character]])->Character{// tests for a winning streak from the bottom left and continues left, then steps upforrowin(0..<board.count).reversed(){forcolin0..<board[row].count{varwinner=testWinType(row,col,board,acrossWinCords)ifwinner!=blank{returnwinner}winner=testWinType(row,col,board,vertWinCords)ifwinner!=blank{returnwinner}winner=testWinType(row,col,board,diagUpWinCords)ifwinner!=blank{returnwinner}winner=testWinType(row,col,board,diagDownWinCords)ifwinner!=blank{returnwinner}}}returnblank}functestWinType(_row:Int,_col:Int,_board:[[Character]],_winCords:[[Int]])->Character{varcountYellow=0varcountRed=0// tests the moves from current location along the path defined in given winCordsformoveinwinCords{letx=row+move[0]lety=col+move[1]ifvalidMove(x,y){letslot=board[x][y]ifslot==blank{break// if there is a blank, theres no possibility of a win}elseifslot==red{countRed+=1}elseifslot==yellow{countYellow+=1}}else{break// if there is an invalid move, theres no possiblity of a win}}ifcountRed==4{returnred}elseifcountYellow==4{returnyellow}returnblank}funcinsert(_aMove:String,_board:[[Character]])->[[Character]]{// split the move into a column letter and player color. Invalid inputs WILL break this.letmove=aMove.split(separator:Character("_"),maxSplits:2,omittingEmptySubsequences:true)letletter=move[0]letplayer=move[1]varcol=0// explictly decipher Letters into column index value.switchletter{case"A":col=0case"B":col=1case"C":col=2case"D":col=3case"E":col=4case"F":col=5case"G":col=6default:// unexpected values shouldnt change the state of the board at all.returnboard}varnewBoard=board// iterate through the board rows starting at the bottom in the given columnforrowin(0..<board.count).reversed(){ifboard[row][col]==blank{ifplayer=="Red"{newBoard[row][col]=redreturnnewBoard}elseifplayer=="Yellow"{newBoard[row][col]=yellowreturnnewBoard}}}// unexpected values shouldnt change the state of the board at all.returnboard}/*
ConnectFour challenge function.
@param pieceList:[String] an ordered list of moves in the format of ColLetter_Color(ie "D_Red" or "F_Yellow")
@return String containing the winner, or Draw
*/funcconnectFour(_pieceList:[String])->String{// create a blank playfieldvarconnect4Grid:[[Character]]=initBoard()// add pieces to the board.formoveinpieceList{connect4Grid=insert(move,connect4Grid)}printBoard(connect4Grid)letwinner=testForWin(connect4Grid)ifwinner==red{return"Red"}elseifwinner==yellow{return"Yellow"}return"Draw"}letexample1=["A_Red","B_Yellow","A_Red","B_Yellow","A_Red","B_Yellow","G_Red","B_Yellow"]letexample2=["A_Red","A_Yellow","B_Red","B_Yellow","C_Red","C_Yellow","D_Red","D_Yellow"]letexample3=["A_Red","G_Yellow","B_Red","F_Yellow","C_Red","E_Yellow"]print("Example1 results: ",connectFour(example1))print("\n")print("Example2 results: ",connectFour(example2))print("\n")print("Example3 results: ",connectFour(example3))print("\n")
I feel like its a bit of a mess, but it works! I didn't do any input validation, and I also assumed that there would only be one winner per move list given for the input, so invalid move list structure and move lists with multiple winners possible to be found might be unreliable. I just spent too much time on this already so I'm cutting my losses! As always, any constructive criticism is always very much appreciated.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
A Swift solution:
Output:
I feel like its a bit of a mess, but it works! I didn't do any input validation, and I also assumed that there would only be one winner per move list given for the input, so invalid move list structure and move lists with multiple winners possible to be found might be unreliable. I just spent too much time on this already so I'm cutting my losses! As always, any constructive criticism is always very much appreciated.