Recent

Author Topic: Repeat Until combo is met  (Read 20062 times)

Bart

  • Hero Member
  • *****
  • Posts: 5714
    • Bart en Mariska's Webstek
Re: Repeat Until combo is met
« Reply #15 on: November 06, 2013, 09:00:49 pm »
Code: [Select]
  Result := (Length(ch) = 3) and (q = 2) and (w = 1);

I used an 'IF then Result :=' that is more fast as $BOOLEVAL optimization is turned OFF by default because the compiled code is then supposed to give up the checks as soon as one of the conditional members is false

First: I just whacked that code together, the real message was thsat in this particular case (only three possibilities) simply comparing it was the way to go (it makes the code better readable).

Second: Boolean shortcut is on by default. That's why you can safely do
Code: [Select]
  Result := (Length(S) <> 0) and (S[1] = Something);

But all this is getting off-topic and, I guess, rather confusing for the topic starter.

Bart

ausdigi

  • Jr. Member
  • **
  • Posts: 52
  • Programmer
    • RNR
Re: Repeat Until combo is met
« Reply #16 on: November 07, 2013, 05:39:07 am »
I think the original poster was trying to do a code short-cut and save themselves some source-code typing. The results of the "abstract exercise" have been interesting.

I think engkin's (and=$71 & xor=$77) is the fastest code assuming we always have three lower-case w's or q's. We were never really told about the possible length of the string although the original post implies lower-case checking only. However engkin's answer doesn't handle the possibility of other characters (we weren't told either way - it would bring up false positives - check yyw). The "proper" code has also been posted (by two people) but I just thought I'd poke this solution at you guys, for something a bit left-of-field (also assumes ch is 3 chars long):
Code: [Select]
until Pos(ch, 'qwqqw') > 0;Least amount of source-code typing but most amount of headaches. :P
« Last Edit: November 07, 2013, 05:41:08 am by ausdigi »
Win10/64: CT 5.7 32&64

sam707

  • Guest
Re: Repeat Until combo is met
« Reply #17 on: November 07, 2013, 06:13:41 am »
@ausdigy

nice shot !  8-)

Harlequin

  • New Member
  • *
  • Posts: 10
Re: Repeat Until combo is met
« Reply #18 on: November 07, 2013, 07:48:15 pm »
:oo holy sh*t so many answers! Thank you!

Although I must say I'm really a beginner at programming and I don't even use functions yet so, after reading tru the answers and realising I wouldn't understand the coding right away what I'm gonna do now is write the program without functions and then slowly I'll try to neat it and make it smaller.

I'm going to fully explain my-self to help you guys help me.

There's this game called DotA 2, and in that game there's a hero named "Invoker". He's a bit different from other heroes in the game. You have to invoke his skills and for that you have to combine Q-W-E in 10 different possibilities (10 skills), then you press R to 'invoke' the skill.

And so, there's the Invoker Trainer where you have to invoke all of his 10 skills as fast as you can.

The name of the skill appears on the screen and you have to put the right combo and press R. Also, it doesn't repeat a skill, after you invoke one it doesn't appear again untill you restart.

[http://dl.dropboxusercontent.com/u/75495922/InvokerTrainer.htm » Click on Classic]

What I want to do as exercise is to write it my-self in pascal!

For the 10 skills I'm going to use case x of.


Code: [Select]
program Invoke;

uses crt;

var randomPossibilities:array [1..10] of integer;
    ch:array [1..3] of char;
    i, cont, x:integer;
   
begin

i:=1;

for cont:=1 to 10 do
 begin
  randomize;
  randomPossibilities[cont]:=random(9);
  x:=randomPossibilities[cont];

  case x of
  0: begin
      if (randomPossibilities[cont]=10) then end
      else
      begin
      randomPossibilities[cont]:=10;
      end;
 

This above was suposed to make it not repeat the skill although it didn't work. How do I make it not repeat after being used? D:

Harlequin

  • New Member
  • *
  • Posts: 10
Re: Repeat Until combo is met
« Reply #19 on: November 07, 2013, 07:52:04 pm »
Also, the code I wrote there

Code: [Select]
repeat
(...)
until (ch:='qqw' or 'qwq' or 'wqq');

Wasn't compiled obvsly. I wrote it when writting the thread. No, I'm not nearly being good at pascal but I knew you would've understood!

ausdigi

  • Jr. Member
  • **
  • Posts: 52
  • Programmer
    • RNR
Re: Repeat Until combo is met
« Reply #20 on: November 08, 2013, 01:34:09 am »
I don't understand the Invoker ("classic" trainer) or what you are trying to do in your code but:
  • You shold only ever call Randomize ONCE in your code (i.e. in your initialisation).
  • If you want a random number from 0 (zero) to 9 you should use Random(10). The Random function returns a number in the range of 0 <= X < Range (i.e. from zero to one less than the number you specify).
  • Do you want your array randomPossibilities to be any random number from 0-9 with duplicates or a unique number?
  • What are you trying to do in your case statement? You seem to be trying to check if one of the values is 10 and if not then set it to 10 but your random number generator will never set a value of 10.
Win10/64: CT 5.7 32&64

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Repeat Until combo is met
« Reply #21 on: November 08, 2013, 05:31:17 am »
You do not provide the complete code of the loop. I have no idea why it did not work I can tell you this though try changing your code to
Code: [Select]
program Invoke;

uses crt;

var randomPossibilities:array [1..10] of integer;
    ch:array [1..3] of char;
    i, cont, x:integer;
   
begin

i:=1;

for cont:=1 to 10 do
 begin
  randomize;
  randomPossibilities[cont]:=random(9);
  x:=randomPossibilities[cont];

  case x of
  0: begin
      if (randomPossibilities[cont]=10) then
        Continue
      else
         randomPossibilities[cont]:=10;
 

Next time try to provide the complete flow of things not the ones you think are relative.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Harlequin

  • New Member
  • *
  • Posts: 10
Re: Repeat Until combo is met
« Reply #22 on: November 08, 2013, 02:18:57 pm »
I don't understand the Invoker ("classic" trainer) or what you are trying to do in your code but:
    It's k, I was expecting DotA 2 players here since it's quite popular, right after League of Legends!

    I want to combine three letters (QWE) in all ways possible (10)! (I think it's called Permutation).

    Although it's really not important to understand this for the code I'll give an example,
    In the screen it will appear one random skill from 10. If it was "Ghost Form" the user would have to type: QQW then press R. The QQW can be in any order. (QWQ or WQQ)

    • Do you want your array randomPossibilities to be any random number from 0-9 with duplicates or a unique number?

    To be a unique every time. To generate 10 numbers, 10 times, never repeating! (I have a better idea of how to do this now actually. Must save all results and make it compare. It's supose to be doing random untill all 10 results are different).

    • What are you trying to do in your case statement? You seem to be trying to check if one of the values is 10 and if not then set it to 10 but your random number generator will never set a value of 10.

    The case is for all the 10 skills:

    0: begin
        writeln ('Cold Snap'); »» this is the skill name, which right combo is 'QQQ'.
        (...)
        end;

    ^ If the key input by user doesn't match QQQ it doesn't come out of the case, so there will be a repeat.

    1: begin
        writeln ('Ice Wall'); »» Another skill name, combo is 'QQE'.
        (...)
        end;

    Ofc that is just so u can sort of visualise what the case is for. (for the all the 10 skills)[/list]
    « Last Edit: November 08, 2013, 02:21:01 pm by Harlequin »

    Harlequin

    • New Member
    • *
    • Posts: 10
    Re: Repeat Until combo is met
    « Reply #23 on: November 08, 2013, 03:33:02 pm »
    Ok, I found it!

    Code: [Select]
    program permutation;

    var a:array[1..10] of integer;
        auxiliar, x, i, n:integer;

    begin
    randomize;

    x:=10;

    for i:=1 to 10 do a[i]:=i; // First put them in order

    for i:=1 to x do
        begin           // Now do permutations, so re-order in a random order
        n:=random(9)+1;
        auxiliar:=a[1];
        a[1]:=a[n];     
        a[n]:=auxiliar;
        end;

    for i:=1 to 10 do writeln (a[i]);

    readln;
    end.


    howardpc

    • Hero Member
    • *****
    • Posts: 4144
    Re: Repeat Until combo is met
    « Reply #24 on: November 08, 2013, 03:33:34 pm »
    I want to combine three letters (QWE) in all ways possible (10)! (I think it's called Permutation).
    The number of permutations of three distinct letters is factorial 3 (3!), which is 6, not 10.
    Or are you allowed duplicate letters among the three?
    Quote
    It's supose to be doing random untill all 10 results are different.
    Whether you allow duplicate letters or not, an approach using letters generated at random is far from ideal. In theory you might never generate some of the possible permutations.
    Better, if you have a specific goal (every possible permutation), is to use an algorithm that generates that directly, rather than a scattershot generation of countless random combinations from which you filter out all duplicates.
    The following code based on a form containing a button and an empty memo shows one way to accomplish this.
    Code: [Select]
    unit main_permutations;

    {$mode objfpc}{$H+}

    interface

    uses
      Forms, StdCtrls;

    type
      TString3 = string[3];

      { TForm1 }

      TForm1 = class(TForm)
        BPermute: TButton;
        MPermutations: TMemo;
        procedure BPermuteClick(Sender: TObject);
      private
        procedure AddToDisplay(const s: string);
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.lfm}

    { TForm1 }

    procedure TForm1.BPermuteClick(Sender: TObject);

      procedure Exchange(var a, b: Char);
      var t: Char;
      begin
        t:=a;
        a:=b;
        b:=t;
      end;

      function Permute(s: TString3; startByte: byte): TString3;
      var n: integer;
      begin
        if startByte >= 3 then
          AddToDisplay(s)
        else
          begin
            for n:= startByte to Length(s) do
             begin
               Exchange(s[n], s[startByte]);
               Permute(s, Succ(startByte));
               Exchange(s[n], s[startByte]);
             end;
          end;
      end;

    begin
      Permute('QWE', 1);
    end;

    procedure TForm1.AddToDisplay(const s: string);
    begin
      MPermutations.Lines.Add(s);
    end;

    end.


    Harlequin

    • New Member
    • *
    • Posts: 10
    Re: Repeat Until combo is met
    « Reply #25 on: November 09, 2013, 12:12:18 pm »
    Nevermind whatever you read so far, here's the update on the situation!

    It is finished!
    Now I just have to copy and paste almost everything + 9 times! (Case 2,3,4,5,6,7,8,9,10)

    Code: [Select]
    program Invoker;

    uses crt;

    var
        a:array[1..10] of integer;
        op:array[1..3] of char;
        ch:char;
        auxiliar, cont, n, i:integer;
        x:boolean;

    begin
    textcolor (15);
    randomize;
    i:=1;

    for cont:=1 to 10 do a[cont]:=cont;

    for cont:=1 to 10 do
        begin
        n:=random(10)+1;
        auxiliar:=a[1];
        a[1]:=a[n];
        a[n]:=auxiliar;
        end;

    for cont:=1 to 10 do
        begin {1}

        case a[cont] of
        1: repeat
           begin
           writeln ('Cold Snap'); {The right combination for this skill is qqq followed by r}
           writeln (op[3],op[2],op[1]);
           if keypressed then
              begin
              ch:=readkey;
              auxiliarch:=ch;
              if (ch=#114) and ((op[1]='q') and (op[2]='q') and (op[3]='q')) then x:=true;
              if (ch=#114) then ch:=#0
              else
                  begin
                  if (op[1]='q') and (op[2]='q') and (op[3]='q') then i:=1;
                  if (op[1]='w') and (op[2]='w') and (op[3]='w') then i:=1;
                  if (op[1]='e') and (op[2]='e') and (op[3]='e') then i:=1;
                  op[3]:=op[2];
                  op[2]:=op[1];
                  op[1]:=ch;
                  i:=i+1;
                  if i>3 then i:=1;
                  end;
              end;
           delay (100);
           clrscr;
           end;
           until (x=true);

        end;     {End of case!}
        end;     {End of Begin 1}

    end.

    This is what was intended ^  :P

    Now I want to reduce the size of this line, if (ch=#114) and ((op[1]='q') and (op[2]='q') and (op[3]='q')) then x:=true;

    The other skills will require lots of ORs and ANDs. Example,

    Code: [Select]
    if (ch=#114) and (((op[1]='q') and (op[2]='w') and (op[3]='w')) or ((op[1]='w') and (op[2]='q') and (op[3]='w')) or ((op[1]='w') and (op[2]='w') and (op[3]='q'))) then x:=true;
    Should I be working with procedures for this?
    « Last Edit: November 09, 2013, 12:19:19 pm by Harlequin »

    engkin

    • Hero Member
    • *****
    • Posts: 3112
    Re: Repeat Until combo is met
    « Reply #26 on: November 09, 2013, 03:43:05 pm »
    The other skills will require lots of ORs and ANDs.

    You have plenty of solutions. Like Eny's solution. I might use:

    Code: [Select]
    x := (ch=#114) and (M[ op[1], op[2], op[3] ]<>0);

    Where M is a magical array, declare it as a global variable, just like your op:

    Code: [Select]
    var
    ..
        M: array['a'..'z','a'..'z','a'..'z'] of byte;

    And fill its contents at the beginning. Here you could automate this part, but for the fun of it I'm not going to show you how  :P, or fill it manually, a line per skill:

    Code: [Select]
      M['q','q','w'] := 1;  M['q','w','q'] := 1;  M['w','q','q'] := 1;
    ...
      M['e','e','r'] := 1;  M['e','r','e'] := 1;  M['r','e','e'] := 1;

    Quote from: Harlequin
    link=topic=22547.msg133552#msg133552 date=1383995538
    Should I be working with procedures for this?

    Not if you don't want to.  :P

    Harlequin

    • New Member
    • *
    • Posts: 10
    Re: Repeat Until combo is met
    « Reply #27 on: November 09, 2013, 06:24:53 pm »
    It's not that I want/don't it's more like, I want to make less repetition! :P

    Still... going to write lots of these :P
    M['q','q','w']:=1;
    M['q','w','q']:=1;
    M['w','q','q']:=1;

    Why is M byte? :3 (Shouldn't it be char?)

    I tested it and it's the same thing puting it like (...)<>0 or (...)=1

    EDIT: I don't know why but with your code the program 'crashes' when I press "R"
    « Last Edit: November 09, 2013, 06:35:16 pm by Harlequin »

    engkin

    • Hero Member
    • *****
    • Posts: 3112
    Re: Repeat Until combo is met
    « Reply #28 on: November 09, 2013, 07:00:26 pm »
    I want to make less repetition! :P

    Still... going to write lots of these :P

    That's why I told you:

    ... you could automate this part, but for the fun of it I'm not going to show you how  :P, ...

    It's a puzzle for you  :P

    EDIT: I don't know why but with your code the program 'crashes' when I press "R"

    Then do *not* press 'R'. Don't blame my code.  ;D It's your program's fault. Now seriously you should learn about debugging your program. It has something to do with bugs.  :P


     

    TinyPortal © 2005-2018