Untitled
unknown
matlab
3 years ago
24 kB
5
Indexable
% EXPLANATION OF SPRITE SHEET (othelloIcons.png) % The majority of the sprite sheet corresponds to ASCII shifted over 1 for % ease of use with Matlab. Since Matlab treats 'abc' as an array like % [97 98 99], the ASCII codes for the respective letters, the sprite sheet % was made such that the indexes 97, 98, and 99 correspond to a, b, and c. % This is true for all printable characters. % OTHER SPRITE VALUES % 1: Empty green tile 2: Black piece with border 3: White piece with border % 4: Empty tile 5: Black piece no border 6: White piece no border % 7: All black 8: Light green (selection) 9: All yellow % 10: Chinese symbol 11: Switch icon clc clear close all % create board from personal icon set symbols = simpleGameEngine("othelloIcons.png",16,16,4,[0,140,0]); % get language from user ( 1 => English, 2 => Spanish ) board = zeros(10,19) + 7; board(4:7,2:18) = 4; board(2,7:13) = 'REVERSI'; board(4,9:11) = ['A' 11 10]; % internationally understood translate icons board(5,2:8) = 'English'; board(5,12:18) = 'Español'; language = 0; drawScene(symbols,board); select = zeros(10,19) + 4; while true drawScene(symbols,select,board); % if player selected a language, wait for a second then switch screens if language ~= 0 pause(.05); if language == 3 pause(.3) end break; end % select is empty aside from yellow boxes to go under selections select = zeros(10,19) + 4; [row, col] = getMouseInput(symbols); if row == 5 if col > 1 && col < 9 language = 1; select(5,2:8) = 9; elseif col > 11 && col < 19 language = 2; select(5,12:18) = 9; end elseif row == 6 if col > 1 && col < 14 language = 3; % name of this language only appears if clicked as easter egg board(6,2:13) = 'tlhIngan Hol'; select(6,2:13) = 9; end end end % build main screen board if language == 1 board(4,2:18) = 'PLAYER1 PLAYER2'; board(5,2:18) = ' Human Human '; board(6,2:18) = ' AI123 AI123 '; board(7,2:18) = ' Start '; board(9,5:15) = 'How to play'; elseif language == 2 board(4,2:18) = 'JUGADOR1 JUGADOR2'; board(5,2:18) = ' Humano Humano '; board(6,2:18) = ' IA 123 IA 123 '; board(7,2:18) = ' Empezar '; board(9,4:16) = 'Cómo se Juega'; elseif language == 3 board(4,2:18) = 'QujwI''1 QujwI''2'; board(5,2:18) = ' Human Human '; board(6,2:18) = 'De'' 123 De'' 123'; board(7,2:18) = ' tagh! '; end % default variables, the difficulty is automatically stored as 2 in case a % user just clicks 'AI' start = false; p1isAI = false; p2isAI = false; difficulty1 = 2; difficulty2 = 2; % MAIN MENU SCREEN while true % select is empty aside from yellow boxes to go under selections select = zeros(10,19) + 4; % puts yellow under selections for Player 1 if p1isAI if language == 1 select(6,3:4) = 9; select(6,4+difficulty1) = 9; elseif language == 2 select(6,3:4) = 9; select(6,5+difficulty1) = 9; elseif language == 3 select(6,2:4) = 9; select(6,5+difficulty1) = 9; end else if language == 1 select(5,3:7) = 9; elseif language == 2 select(5,3:8) = 9; elseif language == 3 select(5,3:7) = 9; end end % puts yellow under selections for Player 2 if p2isAI if language == 1 select(6,13:14) = 9; select(6,14+difficulty2) = 9; elseif language == 2 select(6,12:13) = 9; select(6,14+difficulty2) = 9; elseif language == 3 select(6,12:14) = 9; select(6,15+difficulty2) = 9; end else if language == 1 select(5,13:17) = 9; elseif language == 2 select(5,12:17) = 9; elseif language == 3 select(5,13:17) = 9; end end % draws the menu drawScene(symbols,select,board); % if player selected start, wait for a second then switch screens [row, col] = getMouseInput(symbols); % if player selects start if (language == 1 && row == 7 && col > 7 && col < 13) || ... (language == 2 && row == 7 && col > 6 && col < 14) || ... (language == 3 && row == 7 && col > 7 && col < 13) % put yellow under start if language == 1 select(7,8:12) = 9; elseif language == 2 select(7,7:13) = 9; elseif language == 3 select(7,8:12) = 9; end drawScene(symbols,select,board); pause(.05); % exits the loop break; % if player selects human elseif row == 5 if (language == 1 && col > 2 && col < 8) || ... (language == 2 && col > 2 && col < 9) || ... (language == 3 && col > 2 && col < 8) p1isAI = false; elseif (language == 1 && col > 12 && col < 18) || ... (language == 2 && col > 11 && col < 18) || ... (language == 3 && col > 12 && col < 18) p2isAI = false; end % if player selects AI, assign difficulty elseif row == 6 if (language == 1 && col > 2 && col < 8) || ... (language == 2 && col > 2 && col < 9) || ... (language == 3 && col > 1 && col < 9) p1isAI = true; if language == 1 && col > 4 % '- 4' is the spacing between the column and the actual % number (in English) difficulty1 = col - 4; elseif language == 2 && col > 5 difficulty1 = col - 5; elseif language == 3 && col > 5 difficulty1 = col - 5; end elseif (language == 1 && col > 12 && col < 18) || ... (language == 2 && col > 11 && col < 18) || ... (language == 3 && col > 10 && col < 19) p2isAI = true; if language == 1 && col > 14 difficulty2 = col - 14; elseif language == 2 && col > 14 difficulty2 = col - 14; elseif language == 3 && col > 15 difficulty2 = col - 15; end end % if player selects how to play, show tutorial elseif (language == 1 && row == 9 && col > 4 && col < 16) || ... (language == 2 && row == 9 && col > 3 && col < 17) % show selection for .05 seconds if language == 1 select(9,5:15) = 9; elseif language == 2 select(9,4:16) = 9; end drawScene(symbols,select,board); pause(.05); showTutorial(symbols, language); end end % reset board board = newBoard(language); % start game on black's turn (black always goes first) blacksTurn = true; % keep track of who can move, stop game if neither black/white can whiteCanMove = true; blackCanMove = true; % MAIN GAME LOOP quit = false; while ~quit % for whoever's turn it is, check if they can move while looking % through board if blacksTurn blackCanMove = false; else whiteCanMove = false; end % iterate through all spaces on the board (board(2:9,2:9)) for boardRow = 2:9 for boardCol = 2:9 % gets rid of highlight spaces if board(boardRow, boardCol) == 8 board(boardRow, boardCol) = 1; end % decide whether or not a player can move in a given space if board(boardRow, boardCol) == 1 % iterate through directions from current space for scopeRow = -1:1 for scopeCol = -1:1 % move testRow/testCol in current direction testRow = boardRow + scopeRow; testCol = boardCol + scopeCol; % while the pieces in this direction are % opponent's color while board(testRow, testCol) == 2 + blacksTurn testRow = testRow + scopeRow; testCol = testCol + scopeCol; % if new test space is player's color, then % this is playable space (and player is % able to play) if board(testRow, testCol) == 3 - blacksTurn board(boardRow, boardCol) = 8; if blacksTurn blackCanMove = true; else whiteCanMove = true; end end end end end end end end % if player can move, then they will. Otherwise either turn is % skipped or if nobody can play game ends if (blacksTurn && blackCanMove) || (~blacksTurn && whiteCanMove) % this puts the current score at the bottom board = setCounts(board); % label current turn and draw game board(4, 17) = 6 - blacksTurn; drawScene(symbols, board); % title can have comments from last move, so remove it title(""); % if a human has a turn if (blacksTurn && ~p1isAI) || (~blacksTurn && ~p2isAI) % get a location to play from the player row = 1; col = 1; % until player clicks a highlighted space while board(row,col) ~= 8 [row, col] = getMouseInput(symbols); if board(row,col) ~= 8 % if the player clicks redo if (row == 7 && (col > 10 && col < 19)) % show selection select = zeros(10,19) + 4; select(7,11:18) = 9; drawScene(symbols,select,board); pause(.05); % reset board board = newBoard(language); % start game on black's turn (black always goes first) blacksTurn = true; % keep track of who can move, stop game if neither black/white can whiteCanMove = true; blackCanMove = true; break; elseif (row == 9 && (col > 10 && col < 19)) % show selection select = zeros(10,19) + 4; select(9,11:18) = 9; drawScene(symbols,select,board); pause(.05); % quit game quit = true; break; else if language == 1 title("Error: Invalid Space"); elseif language == 2 title("Error: Espacio Inválido"); end end end end % if AI has a turn else % delay between AI moves pause(.2); % sets difficulty to that of either black or white, % depending on which color current AI is playing difficulty = blacksTurn * difficulty1 + ~blacksTurn * difficulty2; [row, col] = getAIMove(board, blacksTurn, difficulty); end % place piece on the board and switch turn to other player if move % is valid (otherwise the game was probably reset) if (row > 1 && row < 10) && (col > 1 && col < 10) board = updateBoard(board, row, col, blacksTurn); blacksTurn = ~blacksTurn; end elseif ~blackCanMove && ~whiteCanMove % stop game if neither one can play until input % replace the turn label with "GAMEOVER" if language == 1 board(4,11:18) = 'GAMEOVER'; elseif language == 2 board(4,11:18) = ' EL FIN '; end % set final score board = setCounts(board); drawScene(symbols,board); title(""); row = 1; col = 1; % await input while true [row, col] = getMouseInput(symbols); % redo button is clicked if (row == 7 && (col > 10 && col < 19)) % show selection select = zeros(10,19) + 4; select(7,11:18) = 9; drawScene(symbols,select,board); pause(.05); % reset board board = newBoard(language); % start game on black's turn (black always goes first) blacksTurn = true; % keep track of who can move, stop game if neither black/white can whiteCanMove = true; blackCanMove = true; break; % quit button clicked elseif (row == 9 && (col > 10 && col < 19)) % show selection select = zeros(10,19) + 4; select(9,11:18) = 9; drawScene(symbols,select,board); pause(.05); % exit game quit = true; break; end end else % skip turn if one user can't play blacksTurn = ~blacksTurn; end end close; function board = newBoard(language) % set up starting board to all black board = zeros(10,19) + 7; % set game area to green grid board(2:9,2:9) = 1; % set up message area (turn, score, control) board(2:9,11:18) = 4; board(5:6,11:18) = 7; board(8,11:18) = 7; if language == 1 board(2,12:17) = 'Score:'; board(4,12:16) = 'Turn:'; board(7,13:16) = 'Redo'; board(9,13:16) = 'Quit'; elseif language == 2 board(2,11:18) = 'Puntaje:'; board(4,11:16) = 'Turno:'; board(7,12:17) = 'Replay'; board(9,12:17) = 'Cerrar'; elseif language == 3 board(2,11:18) = 'pe''''egh:'; board(4,11:16) = 'yiQuj:'; board(7,13:16) = 'tagh'; board(9,13:15) = 'bup'; end board(3,11) = 5; board(3,18) = 6; % place starting pieces board(5,5) = 2; board(6,6) = 2; board(5,6) = 3; board(6,5) = 3; end function board = setCounts(board) % update score on board blackCt = getCount(board, 2); whiteCt = getCount(board, 3); board(3,13) = 4; board(3, 12:12+(blackCt>9)) = num2str(blackCt); board(3,16) = 4; board(3, 17-(whiteCt>9):17 ) = num2str(whiteCt); end function count = getCount(board, value) % return the number of value on the playable board count = 0; % get number of pieces on board with value for boardRow = 2:9 for boardCol = 2:9 if board(boardRow, boardCol) == value count = count + 1; end end end end function showTutorial(symbols, language) if language == 1 buildBook("RULES: Black always starts. For every move, " + ... "every line between the piece you play and another piece of " + ... "your color separated only by pieces of the opponent's " + ... "color gets flipped to your color. You may only play in " + ... "places where you are able to flip pieces, conveniently " + ... "highlighted in this application. If one player is unable " + ... "to play on their turn, the other player gets an extra " + ... "turn. The game ends when no players are able to play, and " + ... "the winner is determined by the player with the most " + ... "pieces of their color. STRATEGY: Take control of the " + ... "corners. In most games in which one player has 3 of the " + ... "corners, that player wins. Similarly, it is important to " + ... "take control of the edges. GAME INSTRUCTIONS: For each of " + ... "player 1 and player 2 (black and white respectively), " + ... "select human for if they are to be played by a human or AI " + ... "with the corresponding difficulty level if they are to be " + ... "played by an AI. Click start to begin the game.",symbols); elseif language == 2 buildBook("REGLAS: Negro siempre empieza. Para cada turno, " + ... "cada línea seperada solamente por piezas del color del " + ... "adversario se voltea a tu color. Solamente puedes poner " + ... "una pieza en un lugar en cual puedes voltear piezas, " + ... "destacados en esta aplicación. Si un jugador no se puede " + ... "jugar, el otro jugador gana extra turno. El juego termina " + ... "cuando nadie puede jugar, y se sabe el ganador por quién " + ... "tenga la mayoría de las piezas. ESTRATEGÍA: Toma control " + ... "de las esquinas, y también de los bordes.",symbols); end end function buildBook(text, symbols) % prints all of text with precondition that no word in text is longer % than 16 characters in a "book" in which one can search through the % pages. % get array of all words in text words = split(text); line = 2; col = 2; pageCt = 1; % standard blank green page with black border newPage = zeros(10,19) + 7; newPage(2:9,2:18) = 4; newPage(9,2) = '<'; newPage(9,18) = '>'; newPage(9,10) = '×'; % initialize board with single page board = newPage; % gets rid of first '<' board(9,2) = 4; while ~isempty(words) % get char array of first word word = convertStringsToChars(words(1)); % remove first word words = words(2:end); % if word can't fit on current line if col + length(word) > 19 col = 2; % add a page if lines run out, otherwise go to next line if line == 8 board = [board, newPage]; line = 2; pageCt = pageCt + 1; else line = line + 1; end end % add word to board board(line,(pageCt-1)*19+col:(pageCt-1)*19+col+length(word)-1) = word; % increase col accordingly col = col + length(word) + 1; end % remove final increase page button board(9,18 + (pageCt-1)*19) = 4; % display book page = 1; % runs the book until user clicks 'end' while true drawScene(symbols,board(1:end,19*(page-1)+1:19*page)); [row, col] = getMouseInput(symbols); if row == 9 % clicked end if col == 10 break; % clicking back arrow elseif col == 2 && page > 1 page = page - 1; %clicking front arrow elseif col == 18 && page < pageCt page = page + 1; end end end end function board = updateBoard(board, row, col, blacksTurn) % place a piece at the indicated space. Must be a playable space. for scopeRow = -1:1 for scopeCol = -1:1 % test if line can flip in this direction testRow = row + scopeRow; testCol = col + scopeCol; canFlipLine = false; while board(testRow, testCol) == 2 + blacksTurn testRow = testRow + scopeRow; testCol = testCol + scopeCol; if board(testRow, testCol) == 3 - blacksTurn canFlipLine = true; end end % flip line if it can in this direction if canFlipLine while testRow ~= row + scopeRow || testCol ~= col + scopeCol testRow = testRow - scopeRow; testCol = testCol - scopeCol; board(testRow, testCol) = 3 - blacksTurn; end end end end board(row,col) = 3 - blacksTurn; end function [row, col] = getAIMove(board, blacksTurn, difficulty) % returns the row and column that the AI chooses. [rows, cols, scores] = getScores(board, blacksTurn); scores = difficulty .^ (scores + 1); % select a random number up to the the sum of the scores and select the % choose the row and column associated with where that random number % falls on the scores array. sumScores = rand*sum(scores,'all'); count = 0; for i = 1:length(scores) count = count + scores(i); if count > sumScores row = rows(i); col = cols(i); break; end end end function [rows, cols, scores] = getScores(board, blacksTurn) % for each space on the board with an 8, the row and col for that space % is added to the rows and cols arrays and the score (calculated from % consideration of several variables) is % added to the scores array. % length is how many highlighted spaces on the board length = getCount(board, 8); rows = zeros(1,length); cols = zeros(1,length); scores = zeros(1,length); i = 1; for row = 2:9 for col = 2:9 if board(row, col) == 8 rows(i) = row; cols(i) = col; % tests what would happen if player puts piece here testBoard = updateBoard(board, row, col, blacksTurn); opportunities = 0; % sum of space types of all current player's flipped pieces plScore = 0; for testRow = 2:9 for testCol = 2:9 if testBoard(testRow, testCol) == 8 opportunities = opportunities + getSpaceType(testRow, testCol); elseif testBoard(testRow, testCol) == 3 - blacksTurn plScore = plScore + getSpaceType(testRow,testCol); end end end % calculate score scores(i) = getSpaceType(row, col)*10 + plScore - opportunities/2 + 100*(getCount(testBoard, 8) == 0); % should rarely ever be this low, but possible. Regardless, % must be positive. if scores(i) < .1 scores(i) = .1; end i = i + 1; end end end end function spaceType = getSpaceType(row, col) % return spaceType as a number [0,5] as labeled on the strategy sheet % based on the type of space is at the given row and column if (row == 5 || row == 6) && (col == 5 || col == 6) spaceType = 4; % Inner Square around center elseif((row == 4 || row == 7) && (col == 4 || col == 7)) spaceType = 3; % Square outside of the inner square, making the corners of this square % 0 elseif((row >=3 && row <= 8) && (col >= 3 && col <= 8)) spaceType = 2; % Make corners 0 if((row == 3 || row == 8) && (col == 3 || col == 8)) spaceType = 0; end % The rest of the spaces are defaulted to 4 besides the corners and the % adjacent spaces else spaceType = 4; % Make corners 5 if((row == 2 || row == 9) && (col == 2 || col == 9)) spaceType = 5; % Make adjacent spaces 1 elseif(((row == 3 || row == 8) && (col == 2 || col == 9)) || ((row == 2 || row == 9) && (col == 3 || col == 8))) spaceType = 1; end end end
Editor is loading...