Пропускане на ходове (4/5 кодът е завършен, просто имам нужда от малко помощ за стратегията)

Имам лек проблем. Насоките за всеобхватния проблем са следните:

  • Игралната дъска има 31 клетки. Първата е означена като START, последната клетка е END, а останалите клетки са номерирани от 1 до 29.

  • Има трима играчи, A, B и C. Играта започва с всички играчи в клетката START. Играч A винаги е първи, след това B, след това C, след това A и т.н. Играта приключва, когато играч достигне клетката END или след нея.

  • Всеки ход се състои от хвърляне на 8-странен зар и преместване на толкова клетки напред. Въпреки това, ако зарът показва 4, преместете назад толкова много клетки (но не отивайте преди START!); ако зарът показва 6, играчът изобщо не се движи и губи следващия ход. Ако играч попадне на клетка, заета от другия играч, играчът, който е бил на клетката, незабавно скача на START.

Вход: Хвърлянията на 8-странния зар за пет игри. Всяка игра се състои от положителни числа, представляващи хвърлянията, завършващи с 0. Първото число е за играч A, след това B, след това C, след това A и т.н. Всяка игра завършва както е описано по-горе или когато се прочете 0.

Резултат: За всяка игра отпечатайте крайната позиция на играчите A, B и C. Позицията и на тримата играчи трябва да е правилна, за да получите кредит за всеки резултат; няма частичен кредит.

Така че, преди да започна да обяснявам проблема, имам 80% от кода завършен. По никакъв начин не търся някой, който да ми свърши работата, просто търся някой, който евентуално би могъл да ми обясни стратегия, която да използвам за следната част от проблема.

Завърших напълно кода за частта за движение на лабораторията, като например всички случаи на зарове от 1 до 8, с изключение на 6. Сега проблемът ми е, че не знам как да накарам програмата да пропуска ход на играчите И следващия ход ако зарът е хвърлен като 6. С други думи, как да изпълня изискването „пропускам ход и губя следващия ход“? Кодът, който имам досега (работи само за входове без номер 6) е по-долу:

import java.util.Scanner;

public class seniorLab{
    static String input;
    static double parsedInput;
    static int i = 0;
    static int count = 1;
    static int positionA;
    static int positionB;
    static int positionC;
    static int valueOfRoll;
    static boolean aAtEnd;
    static boolean bAtEnd;
    static boolean cAtEnd;

    public seniorLab(){
    }

    static void labLoop(){
        for (int i = 0; i < input.length(); i++){
            if (input.charAt(i) != '0'){
                if (i % 3 == 0){
                    valueOfRoll = charToNum(input.charAt(i));
                    positionA += valueOfRoll;
                    if (positionA == positionB){
                        positionB = 0;
                    } 
                    if (positionA == positionC){
                        positionC = 0;
                    }
                     if (positionA >= 31){
                        aAtEnd = true;
                        break;
                    }
                } else if (i % 3 == 1){
                    valueOfRoll = charToNum(input.charAt(i));
                    positionB += valueOfRoll;
                    if (positionB == positionA){
                        positionA = 0;
                    } 
                    if (positionB == positionC){
                        positionC = 0;
                    }
                    if (positionB >= 31){
                        bAtEnd = true;;
                        break;
                    }
                 } else if (i % 3 == 2){
                   valueOfRoll = charToNum(input.charAt(i));
                    positionC += valueOfRoll;
                    if (positionC == positionA){
                         positionA = 0;
                    }
                    if (positionC == positionB){
                        positionB = 0;
                    }
                    if (positionC >= 31){
                        cAtEnd = true;
                        break;
                    }
                }
            } else if (input.charAt(i) == '0'){
                break;
            }
        }
        System.out.print("Output #" + count + ":  ");
        System.out.print("A-" + positionA + ", B-" + positionB + ", C-" + positionC);
    }

    static int charToNum(char ch){
        switch (ch) {
            case '1': return 1;
            case '2': return 2;
            case '3': return 3;
            case '4': return -4;
            case '5': return 5;
            case '7': return 7;
            case '8': return 8;
        }
        return 0;
    }

    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        System.out.print("Line #" + count + ":  ");
        input = in.nextLine();
        input = input.replaceAll("[,]", "");
        seniorLab sL = new seniorLab();
        sL.labLoop();
    }
}

Благодаря за всяка помощ!


person user2918120    schedule 16.11.2013    source източник
comment
Така че в общи линии звучи така, сякаш имате стойност на позиция за всеки играч, но нямате представа за ходове, различни от този цикъл. Звучи ли правилно?   -  person Dennis Meng    schedule 16.11.2013
comment
Да, мога да проследявам позициите правилно (както в случая, всички тестови случаи, които не включват 6-ци, работят перфектно), но в момента разчитам изцяло на позицията на числата в низа, за да изчисля кой е на ред. Например, позицията на първия знак, когато се модулира с 3, е 0, а за втория знак модулът с 3 е 1, а за третия знак модулът с 3 е 2. Следователно играч А ще ход, когато модулът i е 0, играч B, когато е 1, и играч C, когато е 2. Не знам как да анализирам кой кой ход е прескочил.   -  person user2918120    schedule 16.11.2013
comment
Да, изглежда, че ще трябва да направите нещо малко по-различно с определянето на завоите. Ще ви позволя да опитате няколко пъти.   -  person Dennis Meng    schedule 16.11.2013
comment
Първоначално мислех да използвам 3 булеви стойности, skipA, skipB и skipC, за да определя кой е редът, но в крайна сметка това се провали. След това се опитах да използвам for цикъл, който просто непрекъснато изпълняваше три метода (moveA, moveB и moveC), всички които приемаха булеви стойности в параметрите си и се изпълняваха само ако булевата стойност skipX, която им съответстваше, беше невярна. Това също не успя, защото ще трябва да увелича позицията си на низа. Някак си останах без идеи след това.   -  person user2918120    schedule 16.11.2013
comment

Изпитвам същото при провеждане на тестове под IntelliJ.

В моя случай виновникът се оказа множество версии на игрална рамка по пътя на класа.

От въпроса ви не става ясно дали изпълнявате тестовете от командния ред директно или не, от sbt или от IntelliJ, но в моя случай те работеха добре от sbt, но не и в intellij и успях да разреша проблема чрез претърсвайки моите зависимости на подмодула и гарантирайки, че всички те съответстват на основния проект.

  -  person Dennis Meng    schedule 16.11.2013
comment
Проблемът беше, че ще трябва да знам кога да го настроя на false (това озадачи мозъка ми) и как да стартирам и трите метода, докато достигна края на входния низ от числа. Не можах да го направя в цикъл, защото много пъти входният низ нямаше да се дели напълно на 3 (за всеки играч), което означава, че понякога C ще се движи последен, но понякога B ще се движи последен и същият случай с A.   -  person user2918120    schedule 16.11.2013
comment
Например този въведен низ: 3,7,2,6,5,3,2,4,7,8,5,4,8,2,0 A ще премести 3, B на 7 и C на 2. Тогава A ще хвърли 6 (skipA е зададено на true) и B ще премести 5, C ще премести 3. Тогава A (тъй като сте хвърлили 6 и skipA е вярно) ще загуби реда си, така че B ще премести 2, а C ще ход 4. Проблемът тук е как да накараш A, B и C непрекъснато да правят това и след това как и КОГА да зададеш skipA обратно на false, така че A да може да продължи, след като е бил пропуснат.   -  person user2918120    schedule 16.11.2013
comment
Е, колко време се пропускат? Ако е само един ход, тогава във вашия чек, в истинския случай можете просто да го върнете на false и да не правите хвърлянето.   -  person Dennis Meng    schedule 16.11.2013
comment
Чрез проверката си предполагате ли, че трябва да имам метод, който проверява моите булеви стойности, за да види дали са неверни? Можете ли да поставите това в полукод за мен?   -  person user2918120    schedule 16.11.2013
comment
Изглежда, че тъй като потенциално трябва да пропуснете повече от един ход, обикновеното булево значение може да не е най-добрият начин за проследяване на това. Можете ли да измислите нещо, което би ви позволило да зададете произволен брой завъртания, които да пропуснете вместо това?   -  person scriptocalypse    schedule 16.11.2013


Отговори (1)


По молба очертавам това, което споменах в коментарите в полукод. Публикуване като отговор, тъй като това наистина решава проблема.

Казах по-рано в коментарите, че трябва да опитате нещо различно по отношение на завоите. Едно нещо, което можете да направите, е да поставите играчите на опашка. Тогава вашата игра може да върви нещо подобно

set all positions to 0
set all skip booleans to false
put the three players in the queue in order
for each character in the game string
    while the skip variable for the guy in front is true
        set it to false
        move the guy to the back of the line, leaving a new person in front

    // note that we only reach here if the person in front isn't getting
    // skipped this time. thus, the character corresponds to *his* move

    set the roll to the character that we're at right now
    if the roll is 6
        set skip value for that player to be true
    else
        calculate and modify that player's position as normal
    move player to back of queue

Ето някои от точките с този подход:

  1. Сега променяме позицията нагоре само ако това не е „следващият ход“, пропуснат преди това или ходът, който сте загубили, като хвърлите 6 на този ход.
  2. Частта while the skip variable for the guy in front is true може да стане объркана в зависимост от това как са внедрени другите неща. Тъй като това е вашата програма, ще ви позволя да претеглите плюсовете и минусите на възможните подходи.
  3. Вместо опашка можете да използвате int като променлива, за да обозначите кой е редът (използвайки например: 0 за A, 1 за B, 2 за C) и просто не забравяйте да преминете през 0 -1-2, където иначе бихте ротирали играчи в опашката.

Отказ от отговорност: Не казвам, че това е най-добрият подход за решаване на проблема. Но може поне да ви даде идеи и да ви позволи да разработите сами работещо решение.

person Community    schedule 16.11.2013
comment
здрасти Поставих всичко това в обикновен код и той не работи и знам защо: трябва да загубя текущия И следващия ред. В този случай трябва ли да задам цяло число за броя на пропусканията? Така превключвателят ще върне skipA = 2 и когато skipA стане 0, тогава A ще започне да работи отново - person user2918120; 16.11.2013
comment
Звучи като план. Отговорът ми имаше за цел да ви насочи в правилната посока, а не да хване всичко. Изглежда, че мислите за интересна идея, защо не опитате? - person Dennis Meng; 16.11.2013