Results 1 to 10 of 22

Thread: Four-in-a-row (FlashPascal program)

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Is it just my opinion or you also did some work on AI making it smarter?

  2. #2
    Quote Originally Posted by SilverWarior View Post
    Is it just my opinion or you also did some work on AI making it smarter?
    Indeed, I remade the AI. I hope I made it better.

    The evaluation procedure is more precise. I use an array of all good sequences. Each sequence found increase the result.

    Code:
    const  motifs: array[0..13, 0..1]of string = (
        ('OOOO', 'XXXX'),
        ('OOO.', 'XXX.'),
        ('.OOO', '.XXX'),
        ('OO.O', 'XX.X'),
        ('O.OO', 'X.XX'),
        ('OO..', 'XX..'),
        ('O.O.', 'X.X.'),
        ('O..O', 'X..X'),
        ('.O.O', '.X.X'),
        ('..OO', '..XX'),
        ('O...', 'X...'),
        ('.O..', '.X..'),
        ('..O.', '..X.'),
        ('...O', '...X')
      );
    
    
    const
      demiDroites: array[0..24, 0..3] of integer = (
        (1, 1, +1,  0),
        (1, 2, +1,  0),
        (1, 3, +1,  0),
        (1, 4, +1,  0),
        (1, 5, +1,  0),
        (1, 6, +1,  0),
        (1, 1,  0, +1),
        (2, 1,  0, +1),
        (3, 1,  0, +1),
        (4, 1,  0, +1),
        (5, 1,  0, +1),
        (6, 1,  0, +1),
        (7, 1,  0, +1),
        (1, 1, +1, +1),
        (1, 2, +1, +1),
        (1, 3, +1, +1),
        (1, 4, +1, -1),
        (1, 5, +1, -1),
        (1, 6, +1, -1),
        (7, 1, -1, +1),
        (7, 2, -1, +1),
        (7, 3, -1, +1),
        (7, 4, -1, -1),
        (7, 5, -1, -1),
        (7, 6, -1, -1)
      );
    
    
    function tClasseGrille.Points(const aPion: char): integer;
    var
      i, j, k, l: integer;
      x, y: integer;
      segment: string;
    begin
      result := 0;
      l := Ord(aPion = BLANC);
      
      for i := Low(demiDroites) to High(demiDroites) do
      begin
        x := demiDroites[i, 0];
        y := demiDroites[i, 1];
        
        segment := '       ';
        
        j := 1;
        repeat
          segment[j] := grille[x, y];
          Inc(x, demiDroites[i, 2]);
          Inc(y, demiDroites[i, 3]);
          Inc(j);
        until (x < UN) or (x > SEPT) or (y < UN) or (y > SIX);
        
        for j := Low(motifs) to High(motifs) do
          if Pos(motifs[j, l], segment) > 0 then
          begin
            case j of
              0:
                k := 75000;
              1..4:
                k := 2500;
              5..9:
                k := 50;
              else
                k := 1;
            end;
            Inc(result, k);
          end;
      end;
    end;
    Last edited by Roland Chastain; 19-04-2014 at 07:14 AM.

  3. #3
    Quote Originally Posted by Roland Chastain View Post
    Indeed, I remade the AI. I hope I made it better.
    It made it much harder. So far after about a dozen plays I haven't won even once. Lost two times and the rest times resulted in draw.
    But now the AI moves seems ... artificial. When you are playing AI doesen't just prevent you from winning but on my opinion prevent you even from coming close to winning.
    In all my lays I havent managed to reach a point where I would have tre in a row and AI would be forced to block the fourth one. AI simply folows certain path were it even prevents you to prepare any posible winning situation. And this is a joy killer.

  4. #4
    Quote Originally Posted by SilverWarior View Post
    AI simply follows certain path were it even prevents you to prepare any posible winning situation.
    Yes, it's a very good observation.

    Code:
        if Max(a) >= 2500 then
          result := IndexOf(a, Min(a))
    The a variable is an array of the maximal opponent's score at next move. And 2500 means three stones aligned.

    Quote Originally Posted by SilverWarior View Post
    And this is a joy killer.
    Yes, I see what you mean. I will keep it in mind. Anyway thank you for trying my program and for your instructive report.
    Last edited by Roland Chastain; 19-04-2014 at 10:19 AM.

  5. #5
    All you have to do is add some randomization into your AI calculations which would alow it to make some unsafe move every now and then. This would make AI moves to feel omre human.

    If you need someone to playtest and analyze your game I'm usually up for it. You would be surprised how much I have learned this way.

  6. #6
    hasn't been able to beat me even once, so still needs more improvement

  7. #7
    Quote Originally Posted by SilverWarior View Post
    All you have to do is add some randomization into your AI calculations which would alow it to make some unsafe move every now and then. This would make AI moves to feel more human.

    If you need someone to playtest and analyze your game I'm usually up for it. You would be surprised how much I have learned this way.
    Thank you for your suggestion and for your willingness to help.

    Quote Originally Posted by Dan View Post
    hasn't been able to beat me even once, so still needs more improvement
    Thank you for testing. I hope I will improve it soon.

    Happy Easter!

  8. #8
    I made a quick modification inspired by SilverWarior's suggestion.

    I hope the code is clearer than my explanation would be.

    Code:
        aux := Max(a);
        
        //if Max(a) >= BONUS[3] then
    
        if (aux >= BONUS[4]) or (aux >= BONUS[3]) and (RandomAB(1, 2) < 2) then
          result := IndexOf(a, Min(a))
    And here is an example of a bad move than the previous formula used to avoid : DDCC (computer plays black).
    Attached Images Attached Images
    Attached Files Attached Files
    Last edited by Roland Chastain; 20-04-2014 at 09:49 AM.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •