0

I've been making a multiplayer game of TicTacToe to practice skills and to get into client-server model. Now I'm having trouble sending objects using pickle, because when they get unpickled none of the changes to object attributes are made. I only get init values.

Both client and server receives and sends data correctly because when I try to send built-in types everything works as far as I tested. I have no idea how to resolve this issue.

Code is split into 5 files and I will only post the code of the problematic Class.

import pygame as pg

class Field(pg.Rect):

    def __init__(self, left, top, width, height, field_id):
        super().__init__(left, top, width, height)
        self.field_id = field_id
        self.empty_flag = True
        self.sign = None

    def __reduce__(self):
        return (self.__class__, (self.left, self.top, self.width, self.height, self.field_id))

    def __str__(self):
        return str(self.field_id)

    def set_sign(self, sign=None):
        self.sign = sign

    def draw_field(self, window):
        pg.draw.rect(window, pg.Color("red"), self)

    def field_pressed(self, mouse_pos, sign):
        if self.collidepoint(mouse_pos[0], mouse_pos[1]) and self.empty_flag:
            self.play_field(sign)
            return True
        else:
            return False

    def play_field(self, sign):
        self.empty_flag = False
        self.set_sign(sign)

    def get_id(self):
        return self.field_id

    def get_sign(self):
        return self.sign

    def get_empty_flag(self):
        return self.empty_flag

So, during the game, self.sign is being changed to one of the values "x" or "o" and based on that the images are being blit into the screen. When Player1 makes move e.g. self.sign = "x", after is sent it is self.sign = None.

halfer
  • 19,824
  • 17
  • 99
  • 186
kaktus_car
  • 986
  • 2
  • 11
  • 19
  • Your `__reduce__` function does not include `sign` or `empty`, so when pickled, these will not be included. I wouldn't expect you need this function for a simple data-structure pickle. Try commenting it out, and re-test. – Kingsley Apr 16 '20 at 19:39
  • When I comment it out I get: TypeError: __init__() missing 1 required positional argument: 'field_id' I think this is because of pg.Rect inheritance (maybe this was not a good idea to inherit) and if I add self.sign to __reduce__ I get: TypeError: __init__() takes 6 positional arguments but 7 were given If I am not mistaken it calls __init__() and will overwright all attributes. – kaktus_car Apr 16 '20 at 19:46
  • Of course, you could also add `sign` and `empty_flag` to the `__reduce__` set. – Kingsley Apr 16 '20 at 19:47
  • @Kingsley I've got it to work! somehow... I put all the needed attributes into the `__reduce__` as you suggested and then when creating object i passed `None` and then the final state is preserved after unpickling and its NOT `None`. Honestly, I'm not sure how and why this works but it has solved my problem I hope I'll figure it out eventually. Thank you very much for suggestions and time! – kaktus_car Apr 16 '20 at 20:20

0 Answers0