Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function twos()
- clc
- n = mainmenuprint();
- %Print main menu to ask user what to do
- switch n
- case 1
- %Play new game
- game(zeros(4,4))
- case 2
- %Play game loaded from file
- game(dbread())
- case 0
- %Quit
- clc
- clear
- return
- end
- end
- function c = mainmenuprint()
- %This function displays the homescreen
- %and asks the user what they want to do
- while 1
- clc
- %Bask in the glory of my ASCII art skills.
- %Jk. Generated at http://bigtext.org/
- fprintf('\n ____ ___ _ _ ___ ')
- fprintf('\n|___ \\ / _ \\| || | ( _ ) ')
- fprintf('\n __) | | | | || |_ / _ \\ ')
- fprintf('\n / __/| |_| |__ _| (_) |')
- fprintf('\n|_____|\\___/ |_| \\___/ ')
- fprintf('\n\n-----Welcome to 2048!-----')
- fprintf('\n\n1. New game')
- fprintf('\n2. Load game from file')
- fprintf('\n0. Quit')
- %Takes user input. (It is taken as a string to make sure
- %invalid inputs (like letters) can be ignored)
- c = str2double(input('\n\nMake a choice(0, 1 or 2) and press Enter : ','s'));
- if ~ismember(c,0:2)
- continue
- end
- break
- end
- end
- function game(board)
- %This function is the backbone of the game
- %If the board has less than two full spaces for
- %any reason, it assigns either a 2 or a 4 to two
- %random spaces on the board
- if sum(sum(board ~= 0))<2;
- a = [randperm(4,2)',randperm(4,2)'];
- b = 2.*randi(2,2,1);
- a(:,3) = b;
- board(a(1,1),a(1,2)) = a(1,3);
- board(a(2,1),a(2,2)) = a(2,3);
- end
- clc
- %Prints the board
- printboard(board)
- %Prints the menu
- c = printmenu();
- %A variable that may or may not be useful.
- %It was useful in earlier versions but I am too
- %afraid to take it away now.
- d = 'n';
- %While the board has empty spaces, or is deemed
- %playable by my lovely poss() function.
- while sum(sum(board ==0))>0 || poss(board)
- if strfind('wasd',c)
- %If the input was a direction, move the
- %move the board pieces in that direction
- [board,d] = movewhile(board,c);
- elseif c == 'l'
- %Save the current board to a file and
- %return to the main menu
- dbwrite(board)
- twos()
- return
- elseif c == 'p'
- %Return to the main menu
- twos()
- return
- else
- %If the user enters nothing, ask the
- %user for an input again and restart
- %the loop
- clc
- printboard(board)
- c = printmenu();
- continue
- end
- %This was useful in earlier versions. Now I'm
- %afraid it'll break the code if I remove it,
- %so it stays.
- if d ~= 'n'
- c = d;
- continue
- end
- clc
- printboard(board)
- c= printmenu();
- end
- %When the while loop is over, the user is informed
- %that the game is over and is returned to the main
- %menu.
- fprintf('\n Game Over. :(\n')
- pause(5)
- twos()
- return
- end
- function [board, d] = movewhile(board,k)
- %Moves the board pieces in the desired direction.
- %This is slightly different to how the original
- %game works due to an oversight on my part.
- %It is slightly harder to code my version
- %anyway so I'll just go with saying
- %that I took it as a challenge :)
- %I only explained the case where the option is to move
- %downwards (k == 's') because the rest are the same but with different
- %variables changing.
- %Makes a single-layer padding of NaN-variables
- %around the board.
- d = 'n';
- first = board;
- g = NaN(6,6);
- g(2:5,2:5) = board;
- board = g;
- if k == 's'
- %down
- for r = 4:-1:2
- %Starts on the third row and moves upwards.
- for c = 2:5
- if board(r,c) ~= 0
- %If the piece is non-zero
- if board(r,c) == board(r+1,c)
- %If the piece is the same as the one below it,
- % nullify itself and double the piece below it
- board(r+1,c) = board(r,c).*2;
- board(r,c) = 0;
- elseif board(r+1,c) == 0
- %if the piece below it is empty
- p = r;
- while board(r+1,c) == 0
- %while the piece below it is empty,
- %Move the piece to the space below it
- board(r+1,c) = board(r,c);
- board(r,c) = 0;
- r = r+1;
- end
- r = p;
- end
- end
- end
- end
- elseif k == 'a'
- %left
- for r = 2:5
- for c = 3:5
- if board(r,c) ~= 0
- if board(r,c) == board(r,c-1)
- board(r,c-1) = board(r,c).*2;
- board(r,c) = 0;
- elseif board(r,c-1) == 0
- p = c;
- while board(r,c-1) == 0
- board(r,c-1) = board(r,c);
- board(r,c) = 0;
- c = c-1;
- end
- c = p;
- end
- end
- end
- end
- elseif k == 'd'
- %right
- for r = 2:5
- for c = 4:-1:2
- if board(r,c) ~= 0
- if board(r,c) == board(r,c+1)
- board(r,c+1) = board(r,c).*2;
- board(r,c) = 0;
- elseif board(r,c+1) == 0
- p = c;
- while board(r,c+1) == 0
- board(r,c+1) = board(r,c);
- board(r,c) = 0;
- c = c+1;
- end
- c = p;
- end
- end
- end
- end
- elseif k == 'w'
- %up
- for r = 3:5
- for c = 2:5
- if board(r,c) ~= 0
- if board(r,c) == board(r-1,c)
- board(r-1,c) = board(r,c).*2;
- board(r,c) = 0;
- elseif board(r-1,c) == 0
- p = r;
- while board(r-1,c) == 0
- board(r-1,c) = board(r,c);
- board(r,c) = 0;
- r = r-1;
- end
- r = p;
- end
- end
- end
- end
- end
- %removes the padding of NaNs
- board(1,:) = [];
- board(5,:) = [];
- board(:,1) = [];
- board(:,5) = [];
- %If the board is not unchanged after the move
- %, a 2 or a 4 is added to a random empty
- %spot on the board.
- if ~isequal(board,first)
- [x,y] = find(board==0);
- b = 2.*randi(2);
- c = randi(length(x));
- board(x(c),y(c)) = b;
- end
- end
- function res = poss(board)
- %Checks if the board is still playable even if the
- %board is full
- res = 0;
- %Makes a single-layer padding of NaN-variables
- %around the board.
- z = NaN(6,6);
- z(2:5,2:5) = board;
- %If any of the board pieces has an equal and
- %adjacent board piece, this function returns 1.
- for r = 2:5
- for c = 2:5
- if z(r,c) ~= 0
- if any([z(r-1,c),z(r+1,c),z(r,c+1),z(r,c-1)]==z(r,c));
- res = 1;
- return
- end
- end
- end
- end
- end
- function printboard(board)
- %Prints the board. Not much to be said.
- for i =1:4
- fprintf('\n+----+----+----+----+')
- fprintf('\n|%4d|%4d|%4d|%4d|',board(i,:))
- end
- fprintf('\n+----+----+----+----+\n')
- end
- function res = printmenu()
- %Prints the in-game menu.
- fprintf('\n"w/a/s/d" to move')
- fprintf('\n"l" to save to file')
- fprintf('\n"p" to quit to main menu')
- res = input('\n\nMake your choice and press Enter: ','s');
- %The output is the last character in
- %the input string. I found that while
- %playing fast, I typed in
- %two or more characters at once, so this
- %tries to fix that.
- if ~isempty(res)
- res = res(end);
- end
- end
- function b = dbread()
- %Reads and returns the contents of a
- %user-determined file.
- clc
- s = input('\nEnter file name to read from: ', 's');
- fid = fopen(s,'r');
- if fid == -1
- error('\nFile could not be accessed.')
- else
- for i = 1:4
- b(i,:) = str2num(fgetl(fid));
- end
- end
- fclose(fid);
- end
- function dbwrite(board)
- %Writes the board to a user-determined file
- clc
- s = input('\nEnter file name to save in: ', 's');
- fid = fopen(s, 'w');
- if fid == -1
- error('\nFile could not be accessed.')
- else
- for i = 1:4
- fprintf(fid,'%d %d %d %d\n', board(i,:));
- end
- end
- fclose(fid);
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement