% Function: matlab_spider_solitare
%
% Created by Madison Welch Jan 27, 2007
% Replicates Microsoft Spider Solitare
% Goal of the Game: The goal is to form as many complete sets of like suits.
% Once a complete set is obtained it is removed from the playing deck
% A player wins if all cards have been put into a complete set
%
% Note: To move a card a player clicks once on that card and the once on
% the column where he/she wishes it to be moved. (do not drag and drop)
%
% Function: The main function which runs a game of spider solitare. Called
% only at the beginning of the game. Assigns button down functions to run
% as the game is played.
%
% Other Function Calls:
% matlab_spider_solitare_deal - Deals a set of cards onto the spider solitare board from the
% unrevealed, undistributed part of the deck
% matlab_spider_solitare_move_card - runs when a move is attemped.
% 1. checks to see if the move is a valid one
% 2. moves the card if appropriate
% 3. removes a set of cards if a complete King - Ace of suit is created
% cardplot - a function from the cards toolbox which draws cards to the
% screen
%
% Subfunctions:
% new_board - creates a new game board. Outputs assigned
% position of cards.
%
% Variables:
% level - difficulty level {easy, medium, hard}
% game_board & board - global and local structure that tracks the
% positions of the cards on the game board. Because the number of rows
% in a given column can vary, the indexing of board is the column and
% the indexing of the fields is the row.
% Fields:
% 1: number
% 2: suit
% 3: face_up
% 4: handles
% deck - the unrevealed, undistributed cards. Index by turns a player gets
% to deal out cards. Indexing of fields is the order of the cards, which
% determines to which column they get placed in.
% Fields
% 1: number
% 2: suit
% num_complete_sets - the number of sets that have been complete and thus
% displayed in bottom left
%
function matlab_spider_solitare(level)
global game_board deck num_complete_sets
close all
num_complete_sets = 0;
figure
set(gcf,'MenuBar','none');
tmp = uimenu('Label','&Game');
uimenu(tmp,'Label','&New Easy Game','Callback','matlab_spider_solitare(''easy'')');
uimenu(tmp,'Label','&New Medium Game','Callback','matlab_spider_solitare(''medium'')');
uimenu(tmp,'Label','&New Hard Game','Callback','matlab_spider_solitare(''hard'')');
if ~exist('level')
level = 'easy';
end
[board,deck] = new_board(level); %creates new game board. Outputs assigned position of cards.
cardplot([0 10 0 5],[0 .7 0]); % create felt background
set(gcf, 'Units','normalized');
set(gcf,'Position',[0.0503 0.0451 0.9010 0.8657]);
% Draw the cards on the screen (according to which card was assigned to
% which position in variable board)
% Only the last card in each column is placed face up
for i = 1:10
for j = 1:length(board(i).number)
if j == length(board(i).number)
h = cardplot(i-0.85,4-(j*0.2),1,board(i).number(j),char(board(i).suit(j)));
board(i).face_up(j) = true;
board(i).handles(j) = {h};
else
h = cardplot(i-0.85,4-(j*0.2),1,0,char(board(i).suit(j)));
board(i).face_up(j) = false;
board(i).handles(j) = {h};
end
set(h,'UserData',h);
set(h,'ButtonDownFcn',['matlab_spider_solitare_move_card(',num2str(i),',',num2str(j),')']);
end
end
% Set the ButtonDownFunction of the unrevealed, undistributed portion of the
% deck to deal when the card is clicked on
for k = 0:5-1
h = cardplot(9-0.2*k,0,1,0,'heart');
set(h,'UserData',h);
set(h,'ButtonDownFcn',['matlab_spider_solitare_deal']);
end
game_board = board;
%% New Board Function
function [board,deck] = new_board(level)
% How many suits are going to be used?
switch true
case strcmp(level,'easy')
possible_suits(1:4,:) = ones(4,1)*[1 2 3 4];
case strcmp(level,'medium')
possible_suits(1,:) = [1 2];
possible_suits(2:4,:) = ones(3,1)*[3 4];
case strcmp(level,'hard')
possible_suits(1,:) = 1;
possible_suits(2,:) = 2;
possible_suits(3,:) = 3;
possible_suits(4,:) = 4;
end
my_order = randperm(52*2); % randomize card locations
num_of_cols = 10;
for i = 1:num_of_cols
board(i).number = [];
board(i).suit = {};
deck(i).number = [];
deck(i).suit = {};
end
% Assign the cards to positions on the game board. Only 54 out of the total 104 are
% assigned to the gameboard.
for i = 1:54
j = my_order(i);
if j >52
j = j -52;
end
board_index = i - (ceil(i/num_of_cols)-1)*num_of_cols;
board(board_index).number = vertcat(board(board_index).number, j-(ceil(j/13)-1)*13);
switch true
case ismember(ceil(j/13),possible_suits(1,:))
board(board_index).suit(end+1) = {'club'};
case ismember(ceil(j/13),possible_suits(2,:))
board(board_index).suit(end+1) = {'diamond'};
case ismember(ceil(j/13),possible_suits(3,:))
board(board_index).suit(end+1) = {'heart'};
case ismember(ceil(j/13),possible_suits(4,:))
board(board_index).suit(end+1) = {'spade'};
end
end
% Assigns the remaining cards to the unrevealed, undistributed deck
for i = 55:52*2
j = my_order(i);
if j >52
j = j -52;
end
board_index = i - (ceil(i/num_of_cols)-1)*num_of_cols;
deck(board_index).number = vertcat(deck(board_index).number, j-(ceil(j/13)-1)*13);
switch true
case ismember(ceil(j/13),possible_suits(1,:))
deck(board_index).suit(end+1) = {'club'};
case ismember(ceil(j/13),possible_suits(2,:))
deck(board_index).suit(end+1) = {'diamond'};
case ismember(ceil(j/13),possible_suits(3,:))
deck(board_index).suit(end+1) = {'heart'};
case ismember(ceil(j/13),possible_suits(4,:))
deck(board_index).suit(end+1) = {'spade'};
end
end