% unplay 2 % A single-turn unplay program for Tchukaruma. % Tells all of the possible previous board states % and also tells a list of the correlating choices % that would have been made. % By Rex Ford % Collecting information % bins = input('Please enter the number of bins.'); function unplayo % calculates the number of stones obtained % by making a certain choice on a board function [score,board] = advantage(board,choice) number_there=board(choice); board(choice)=0; pos=choice; for x=1:number_there pos=mod(pos,length(board))+1; if(pos==choice) pos=mod(pos,length(board))+1; end board(pos)=board(pos)+1; end % now, we must steal! score=0; while((board(pos)==2 || board(pos)==3) && ~same_side(board,choice,pos)) score=score+board(pos); board(pos)=0; pos=pos-1; if(pos==0) pos=length(board); end end end % calculates the payoff matrix % for a given board function payoff=pom(board) n=length(board)/2; payoff=zeros(n,n); for x=1:n [p,board2]=advantage(board,x); for y=1:n q=advantage(board2,y+n); payoff(x,y)=p-q; end end end function skip=find_skip(state) % finding the number we are skipping skip=1; while(state(skip)~=0 && skip<3) skip=skip+1; end end function [fin_state,choice] = unplay_wrapping(state,start_pos,wraps) pos=start_pos; collection=0; % finding the lowest value that isn't the skip bin skip=find_skip(state); while(state(pos)>0 || wraps>0) if(pos==skip && wraps>0) wraps=wraps-1; if(pos>1) pos=pos-1; else pos=length(state); end elseif(pos~=skip) state(pos)=state(pos)-1; collection=collection+1; if(pos>1) pos=pos-1; else pos=length(state); end end end state(pos)=collection; fin_state=state; choice=pos; end function [fin_states,choices] = unplay(state,start_pos) fin_states=zeros(1,length(state)); choices=zeros(1,1); skip=find_skip(state); % start 'lowest' on a non-zero lowest=1; while(state(lowest)==0) lowest=lowest+1; end %set 'lowest' to the index of the min for q=1:length(state) if(state(q)~=0 && state(q) < state(lowest) && q~=skip) lowest=q; end end for wraps=0:state(lowest) [fin_states(wraps+1,:),choices(wraps+1,1)] = unplay_wrapping(state,start_pos,wraps); end end % tells if a position is on 'my' side function is_it = my_side(state,x) is_it=same_side(state,1,x); end % are these two positions on the same side? function is_it =same_side(state,x,y) is_it=false; n=length(state)/2; if(x>n && y>n) is_it=true; end if(x<=n && y<=n) is_it=true; end end function [good_answers,good_choices]=filter_results(answers,choices) x=1; [the_length,the_width]=size(answers); while(x<=the_length) the_min = min(answers(x,:)); the_right_min = min(answers(x,floor(the_width/2)+1:the_width)); if(the_min<0 || the_right_min>0 || choices(x)>the_width/2) answers(x,:)=[]; choices(x,:)=[]; x=x-1; [the_length,the_width]=size(answers); end x=x+1; end good_answers=answers; good_choices=choices; end function amount=zero_length(state,x) k=0; while(x-k>length(state)/2 && state(x-k)==0) k=k+1; end amount=k; end function the_array=to_bin_array(x,width) bin=dec2bin(x); [bin_length,bin_width]=size(bin); the_array=zeros(1,width); for idx=1:bin_width the_array(idx)=bin(bin_width-idx+1)-48; end end %% Here is the beginning of the actual program: bins=input('how many bins? '); while(mod(bins,2)~=0) bins=input('you must enter an even number. '); end state=zeros(1,bins); for i=1:bins fprintf('bin %i: ',i); state(i)=input('how many? '); end state % Here is the meat: answers=zeros(1,length(state)); choices=zeros(1,1); original_state=state; for j=length(state):-1:1 if(state(j)==0 && same_side(state,1,j)==false) num_zeros=zero_length(state,j); for b=0:2^(num_zeros)-1 my_array=to_bin_array(b,num_zeros); my_array=my_array+ones(size(my_array))*2; state(j-num_zeros+1:j)=my_array(1,1:num_zeros); [new_answers,new_choices]=unplay(state,j); answers=[answers;new_answers]; choices=[choices;new_choices]; state=original_state; end %j=j-num_zeros; elseif(state(j)~=0) [new_answers,new_choices]=unplay(state,j); answers=[answers;new_answers]; choices=[choices;new_choices]; state=original_state; end end answers(1,:)=[]; choices(1,:)=[]; [answers,choices]=filter_results(answers,choices); for t=1:size(answers) fprintf('state %i :',t); answers(t,:) choice=choices(t) payoff_matrix=pom(answers(t,:)) end end