Skip to content

ilchoTaleski/FruityMatch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 

Repository files navigation

FruityMatch

За финалната верзија на играта со .exe фајлот отворете го branch-от Game

Краток опис:

Апликацијата што ја развивавме беше инспирирана од класичната игра на табла Mastermind. Нашата варијанта Fruity Match користи сличен начин на игра со тоа што за кодни зборови се користат комбинации од овошја. Имплементиравме игра со реален противник, како и игра против компјутер. Уште повеќе, овозможивме зачувување на корисници и рангирање на истите во однос на освоените поени во текот на играта.

Упатство за користење:

Доколку играта се стартува прв пат, од играчот ќе биде побарано да креира корисник со внесување на име и одбирање на аватар. Внесувањето на корисник е задолжително и апликацијата нема да се стартува доколку не се создаде барем еден корисник. Во спротивно, апликацијата се стартува со претходно логираниот корисник (само еден корисник е логиран и прикажан на почетниот екран од креираните корисници).

Нова игра:

Нова игра се започнува со кликање во било кој дел од почетниот екран.

Од корисникот се бара да одбере начин на игра, дали ќе игра против друг корисник или ќе игра против компјутерот. Доколку одбере да игра против друг играч потребно е да се избере корисник од листата на корисници за вториот играч, или доколку таков не постои потребно е да се креира.

На следниот екран се врши избирање на кодовите.

Најпрво првиот играч создава код со кликање на овошките од горниот лев дел на екранот. За успешен код се смета кодот кој има 4 различни овошки. Кога играчот ќе ја состави комбинацијата притиска на копчето "Lock combination" и со притискање на ова копче таа комбинација се зачувува и се крие од другиот играч. Потоа и другиот играч го прави истото. Откако двајцата играчи ќе ги изберат своите скриени кодови, играта е започната. Доколку играчот одбере да игра против компјутерот, на екранот за бирање на комбинација играчот го бира својот таен код, додека пак компјутерот генерира свој таен код. Поентата на играта е да се погоди кодот што го внесил противникот во помалку чекори од противникот. Во апликацијата е овозможено и упатство за како да се игра играта, како и кои контроли се овозможени и која функција ја имаат истите.

Упатство за играта

Откако ќе се одберат комбинациите, играчите пробуваат да го погодат кодот на противникот. Играчот кој е на потег е обележан со трепкање на неговитот соодветен аватар. Поставување на код за погодување се прави со одбирање на овошје од големите садови и поставување на целната чинија на таблата. Чиниите врз кои може да се поставува овошје се обележани со црвено. Поставување на овошје на чиниите се врши на два начини: со влечење на посакуваното овошје врз посакуваната чинија и со двоен клик или десен клик врз посакуваното овошје што го мести овошјето на првата слободна чинија. Кога играчот ќе биде задоволен со својот избор на овошја за погодување, кликнува на салфетите веднаш до чиниите со овошјата. Со нивно кликнување се прикажува резултат. Синиот резултат Correct Fruit & Position кажува колку од овошјата се точни и на точна позиција, додека пак црниот резултат Correct Fruit Incorrect Position кажува колку од останатите овошја се точни, но на грешна позиција. Овие резултати помагаат потоа играчите да направат претпоставки во следните чекори. Играта продолжува се додека не се се исполни цела табла со овошја, со победа на едниот играч или пак со нерешен резултат (доколку и двајцата играчи го погодат кодот во ист број на погодоци).

Корисници

Предуслов за стартување на апликацијата е да има регистрирано најмално еден корисник. Доколку апликацијата се стартува прв пат овозможено е негово креирање. Со притискање на копчето "Change User" на почетниот екран овозможено е менување на логираниот корисник, како и додавање на нов корисник со притискање на копчето "Add new user" и бришење на корисници со "Remove user". При креирањето на корисник е овозможено бирање од 12 слики како аватар за корисникот, како и внесување на корисничко име. Овозможено е и менување на постоечкиот аватар и името на постоечки корисник.

Резултати

После секоја завршена игра, се ажурираат бројот на победи, порази и нерешени игри на корисниците. Секоја победа се вреднува со 10 поени, секој нерешен резултат се вреднува со 5 поени и секој пораз се вреднува со 0 поени. Овие податоци како и другите податоци за корисниците се серијализирааат, што овозможува за Систем за рангирање на најдобрите играчи, кој се прикажува со притискање на копчето "Rankings" на главниот екран.

Податочни структури

Податоците за апликацијата се групирани на следниот начин: Секој тип на овојше изведува од класата Fruit. Секоја колекција на овошја изведува од класата FruitCollection. Сите колекции на овошја заедно ја формираат класата FruitDocument. Постојат класи кои се задолжени за салфетите (Napkin, NapkinCollection) и чиниите (LittlePlate, LittlePlates) на интерфејсот. Главните информации на секој играч се чуваат во објекти од класата Player. Најпосле информациите и методите на секоја игра се чуваат во класата Game. Корисниците се чуваат во класата User во која е овозможена серијализација и чии информации се чуваат во папката со име "Users". Најпосле во класата Automatic Game е имплементиран five-guess алгоритамот на Donald Knuth кој ја овозможува играта против компјутерот. Алгоритамот е базиран на прогресивно редуцирање на можните кодови. Во методот initializeList, се иницијализираат сите можни кодови кои се 6^4 = 1296 можни комбинации.

public void initializeList()
        {
            for (int i = 1; i <= 6; i++)
            {
                for (int j = 1; j <= 6; j++)
                {
                    for (int k = 1; k <= 6; k++)
                    {
                        for (int l = 1; l <= 6; l++)
                        {
                            String s = i.ToString() + j.ToString() + k.ToString() + l.ToString();
                            combinations.Add(s);
                            combinationsForDelete.Add(s);
                        }
                    }
                }
            }
        }

Со методот deleteImpossible, се бришат сите комбинации кој не се возможни во однос на претходниот резултат.

public void deleteImpossible(String result, string combination)
        {
            List<String> removed = new List<string>();
            foreach (String comb in combinationsForDelete)
            {
                // if comb was the real combination it should give the same result
                if (Match(combination, comb) != result)
                {
                    removed.Add(comb);
                }
            }
            combinationsForDelete.RemoveAll(a => removed.Contains(a));
        }

Резултатот се пресметува со помош на функцијата Match што враќа број на погодени овошја на точна позиција и погодени овошја на неточна позиција претворени во стринг.

public String Match(String code, String playerCombination)
        {

            int counterPlaces = 0, counterFruitsOnly = 0;
            List<Char> guessCode = new List<Char>()
            {
                code[0],
                code[1],
                code[2],
                code[3]
            };

            List<Char> trueCode = new List<Char>()
            {
                playerCombination[0],
                playerCombination[1],
                playerCombination[2],
                playerCombination[3]
            };


            for (int i = 0; i < 4; i++)
            {
                char gC = guessCode[i];
                char tC = trueCode[i];

                if (gC == tC)
                {
                    counterPlaces++;
                }
            }

            for (int i = 0; i < 4; i++)
            {
                char tC = trueCode[i];
                for (int j = 0; j < guessCode.Count; j++)
                {
                    char gC = guessCode[j];
                    if (tC == gC)
                    {
                        counterFruitsOnly++;
                        guessCode.RemoveAt(j);
                        break;
                    }
                }
            }
            counterFruitsOnly = counterFruitsOnly - counterPlaces;
            return counterPlaces.ToString() + counterFruitsOnly.ToString();

        }

Тоа се комбинациите што како решение во однос на претходниот резултат не го даваат истиот резултат за проверената комбинација, па поради тоа тие се исфрлаат од листата. Методот nextCombinationByMinMax работи на техниката на MinMax, такашто од сите 1296 можни комбинации се бара најповолната, такашто, се пресметува бројот на елементи кои би биле исфрлени со помош на методот countImpossible при било кој резултат за дадената комбинација.

 public int countImpossible(String result, string combination)
        {
            int counter = 0;
            foreach (String comb in combinationsForDelete)
            {
                // if comb was the real combination it should give the same result
                if (Match(combination, comb) != result)
                {
                    counter++;
                }
            }
            return counter;
        }
public String nextCombinationByMinMax()
        {
            Dictionary<int, String> score = new Dictionary<int, String>();
            foreach (String s in combinationsForDelete)
            {
                List<int> numberOfImpossibles = new List<int>();
                numberOfImpossibles.Add(countImpossible("00", s));
                numberOfImpossibles.Add(countImpossible("10", s));
                numberOfImpossibles.Add(countImpossible("01", s));
                numberOfImpossibles.Add(countImpossible("11", s));
                numberOfImpossibles.Add(countImpossible("20", s));
                numberOfImpossibles.Add(countImpossible("02", s));
                numberOfImpossibles.Add(countImpossible("03", s));
                numberOfImpossibles.Add(countImpossible("04", s));
                numberOfImpossibles.Add(countImpossible("40", s));
                numberOfImpossibles.Add(countImpossible("22", s));
                numberOfImpossibles.Add(countImpossible("21", s));
                numberOfImpossibles.Add(countImpossible("12", s));
                numberOfImpossibles.Add(countImpossible("30", s));
                numberOfImpossibles.Add(countImpossible("13", s));

                numberOfImpossibles.Sort();


                score[numberOfImpossibles.Min()] = s;
            }
            int maxValue = score.Keys.Max();
            return score[maxValue];

        }

Од сите бројки за сите резултати се бира минималната и се поставува како score на комбинацијата. Потоа се враќа како резултат, комбинацијата која има најголем score.

Изработено од:

Илчо Талески | 161019

Андреј Попорданоски | 161150

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages