root/src/apps/sudoku/SudokuField.h
/*
 * Copyright 2007-2012, Axel Dörfler, axeld@pinc-software.de.
 * Distributed under the terms of the MIT License.
 */
#ifndef SUDOKU_FIELD_H
#define SUDOKU_FIELD_H


#include <Archivable.h>
#include <SupportDefs.h>


enum {
        kInitialValue   = 0x01,
};


class SudokuField : public BArchivable {
public:
                                                                SudokuField(uint32 size);
                                                                SudokuField(const BMessage* archive);
                                                                SudokuField(const SudokuField& other);
        virtual                                         ~SudokuField();

        status_t                                        InitCheck();

        virtual status_t                        Archive(BMessage* archive, bool deep) const;
        static  SudokuField*            Instantiate(BMessage* archive);

                        status_t                        SetTo(char base, const char* data);
                        void                            SetTo(const SudokuField* other);
                        void                            Reset();

                        bool                            IsSolved() const;
                        bool                            IsEmpty() const;
                        bool                            IsValueCompleted(uint32 value) const;

                        uint32                          Size() const { return fSize; }
                        uint32                          BlockSize() const { return fBlockSize; }

                        void                            SetHintMaskAt(uint32 x, uint32 y,
                                                                        uint32 hintMask);
                        uint32                          HintMaskAt(uint32 x, uint32 y) const;
                        bool                            HasHint(uint32 x, uint32 y, uint32 value) const;

                        void                            SetValidMaskAt(uint32 x, uint32 y,
                                                                        uint32 validMask);
                        uint32                          ValidMaskAt(uint32 x, uint32 y) const;
                        bool                            IsValid(uint32 x, uint32 y, uint32 value) const;

                        void                            SetFlagsAt(uint32 x, uint32 y, uint32 flags);
                        uint32                          FlagsAt(uint32 x, uint32 y) const;
                        bool                            IsInitialValue(uint32 x, uint32 y) const;

                        void                            SetValueAt(uint32 x, uint32 y, uint32 value,
                                                                        bool setSolved = false);
                        uint32                          ValueAt(uint32 x, uint32 y) const;

                        void                            Dump();

private:
        struct field {
                field();

                uint32          hint_mask;
                uint32          valid_mask;
                uint32          flags;
                uint32          value;
        };

                        bool                            _ValidValueAt(uint32 x, uint32 y) const;
                        void                            _ComputeValidMask(uint32 x, uint32 y,
                                                                        bool setSolved);
                        void                            _UpdateValidMaskChanged(uint32 x, uint32 y,
                                                                        bool setSolved);
                        const field&            _FieldAt(uint32 x, uint32 y) const;
                        field&                          _FieldAt(uint32 x, uint32 y);

private:
                        uint32                          fSize;
                        uint32                          fBlockSize;
                        uint32                          fMaxMask;
                        field*                          fFields;
};


#endif  // SUDOKU_FIELD_H