help with basic 2048 game function

25 views (last 30 days)
hi
i'm a super basic user, i barely know how to code. i tried to create a very simple function that reacreate the game '2048' with a 4x4 matrix serving as the palyground.
it's really rudimentary and so mane lines are written poorly (i would like to say creatively )because i don't know better. I also know it's written in such an uneffincent way.
but in my mind it should at least work. and it doesn't.
now, i tried to comment trough what i tried to code the machine to do. Is there anyone willing to get peek at the code and tell me what conceptual mistakes i've done?
thank you in advance
function [a] = game2048(a)
%%the user is asked to run the funcion with a random variable a, that is
%%overwritten and initialized as zeros(4,4) if it isnt a 4X4 matrix
%%(it's possible to cheat by inputting a solved problem)
%%(dunno how to make a function accept no input)
if size(a)~=[4,4]
a=zeros(4,4);
ii=1+round(9*rand);
%a random value(10% is 4, 90% is 2) is given to a random cell
if ii>1
a(1+round(3*rand),1+round(3*rand))=2
else
a(1+round(3*rand),1+round(3*rand))=4
end
end
%%the user is asked with a direction to drag the cells to
direzione=input('direzione? usa WASD','s');
if isempty(direzione)%%control over the imput
direzione=input('direzione? usa solo WASD','s');
end
a1=zeros(4,4);
while a1~=a %%an initial state of the matrix is being saved, to check is there are
%%no more passages to be done(if the last while cycle has as output the input, no more
%%work has to be done)
a1=a;
if direzione=='w'%%2 checks are made, is a cell is empty, the next one in the direction of the move is cut-pasted onto it, if it has the same value the firs one gets doubled and the second one nullified
for jj=1:3 %%2 passages of checks are made for each move, across the matrix. first going against the direction of the move(last row/column of this passage is not included), and "indented" in it going perpendicularly to it across the matrix
for ii=1:4
if a(jj,ii)==0
a(jj,ii)=a(jj,ii+1);
a(jj,ii+1)=0;
elseif a(jj,ii)==a(jj,ii+1)
a(jj,ii)=a(jj,ii)*2;
a(jj,ii+1)=0;
end
end
end
elseif direzione=='s'
for jj=flipr(2:4)
for ii=1:4
if a(jj,ii)==0
a(jj,ii)=a(jj,ii-1);
a(jj,ii-1)=0;
elseif a(jj,ii)==a(jj,ii-1)
a(jj,ii)=a(jj,ii)*2;
a(jj,ii-1)=0;
end
end
end
elseif direzione=='a'
for ii=1:3
for jj=1:4
if a(jj,ii)==0
a(jj,ii)=a(jj,ii+1);
a(jj+1,ii)=0;
elseif a(jj,ii)==a(jj,ii+1)
a(jj,ii)=a(jj,ii)*2;
a(jj,ii+1)=0;
end
end
end
elseif direzione=='d'
for ii=flipr(2:4)
for jj=1:4
if a(jj,ii)==0
a(jj,ii)=a(jj-1,ii);
a(jj-1,ii)=0;
elseif a(jj,ii)==a(jj-1,ii)
a(jj,ii)=a(jj,ii)*2;
a(jj-1,ii)=0;
end
end
end
else
direzione=input('direzione? usa SOLO WASD','s');%%control over the imput
end
end
hh=1;
kk=1;
while a(hh,kk)~=0%%a random value(10% is 4, 90% is 2) is given to a random cell that is empty
hh=1+round(3*rand);
kk=1+round(3*rand);
end
ii=1+round(9*rand);
if ii>1
a(hh,kk)=2
else
a(hh,kk)=4
end
if max(max(a))==2048%% look for the "2048" tile-> user won
input('hai vinto');
else
if min(min(a))==0%%if there is any empty tile, the game keeps going, the function calls itself with the current state as input
game2048(a);
else%%if none of the above is true, the user lost the game
c=input('hai perso, vuoi rigiocare? y/n','s');
if isempty(c)||c~='y'||c~='n'
c=input('hai perso, vuoi rigiocare? y/n','s');
end
if c=='y'
game2048(zeros);
else
clear a;a='ciao';
end
end
end
end
  2 Comments
the cyclist
the cyclist on 2 Aug 2019
For testing purpose, I would suggest you put the line
rng default
at the beginning, so that your code is reproducible, giving the same error each time. Take it out later, so that the game is random again.
It would be helpful if you were to tell us specifically what you mean by "it doesn't work".
Jad Michele Samuel Musallam
Thank you for the "method" advice, i didn't think that the input states for the rand functions were to determine such difference in behavior across different istances to the extend that they have to be care of.
apologize for the poor explanation.I honestly did not expect get such exstensive, detailed feedback, even more so in such a short span of time.
the main problem the cod have is that it does't responds to the input given by the user, each time just updating the playfield with a new spawn cell.
before posting i tried to hand-writing each state of the variable after every instruction and I was not understanding the behavior the program had.
Surely the many mistakes alredy pointed out contribued to that.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 2 Aug 2019
Edited: Guillaume on 2 Aug 2019
I'll be editing this answer as I read the code.
---edit: the main reason for your code not working is at the end of the answer. I'm not looking at the rest of the code.
I have only looked at the beginning of the code. Already:
ii=1+round(9*rand);
%a random value(10% is 4, 90% is 2) is given to a random cell
if ii > 1
%...
else
%...
end
A simpler way to write that is:
ii = randi(10); %random integer between 1 and 10. Uniform distribution.
if ii > 1
%...
else
%...
end
which has the added benefit of actually giving you a uniform distribution and combined with the if test does give you 90%-10% probability. Your method doesn't, it's 95%-5%
>> histogram(1+round(9*rand(1, 1e5)), 'BinMethod', 'integers', 'Normalization', pdf)
I'll let you work out why it's not uniform at the edges.
--------
direzione=input('direzione? usa WASD','s');
if isempty(direzione)%%control over the imput
direzione=input('direzione? usa solo WASD','s');
end
You ask for input, and if it's empty ask again. Why if the user again enter nothing. You continue as if all was well. What if the user did enter something but it's invalid.
The best way to cope with both is with a while loop:
direzione = ''; %start with invalid input so we prompt at least once
while ~ismember(direzione, 'wsad') %if direzione is not one of 'w', 's', 'a' or 'd'
direzione=lower(input('direzione? usa solo WASD','s')); %prompt again. I'm also converting to lowercase, since that's the only thing you test later on
end
-------
while a1~=a
Major bug there! a1 and a are matrices, so a1~=a is a logical matrix (4x4) of true and false values (0 and 1). What does while consider true when you pass it a logical matrix?
The condition is only true if all the elements of the matrix is true. Therefore, the while loop will only be entered if all the element of a1 are different from a. If even one element of a1 is the same as the corresponding element of a, then the condition is false, and you skip the while.
You actually meant to enter the while if any element of a1 differs from a, you could have written that as:
while any(a1~=a, 'all') %r2018b for the 'all' option, earlier versions use any(a1(:) ~= a(:))
or simpler not do an element by element comparison and just ask matlab are the matrices the same with isequal:
while ~isequal(a1, a)
  1 Comment
Jad Michele Samuel Musallam
Thank you for the time to lay out such an extesive answer, to what surely was, as an afterthough, at best a misplaced call for help. the hope it was not not too bad use of your time, i'll do my best to make the most of it.

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB in Help Center and File Exchange

Tags

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!