from flask import Flask, request, jsonify, render_template_string, session, send_from_directory
import numpy as np
from copy import deepcopy
import os

app = Flask(__name__)
app.secret_key = "fea7c212f01dbf6a9da79c1a2b0ee570ba179020a3853977"


# Function to convert numbers to Persian numerals
def to_persian_num(number):
    persian_nums = {'0': '۰', '1': '۱', '2': '۲', '3': '۳', '4': '۴',
                    '5': '۵', '6': '۶', '7': '۷', '8': '۸', '9': '۹'}
    return ''.join(persian_nums[digit] for digit in str(number))




@app.route('/')
def welcome():
    # Serve the welcome.html as the landing page
    return send_from_directory('/var/www/pilapila.net', 'welcome.html')

@app.route('/game')
def game():
    visitor_count = 0
    # Path to the counter file
    counter_path = '/var/www/pilapila.net/counter.txt'
    # Read the current visitor count
    with open(counter_path, 'r') as f:
        visitor_count = int(f.read().strip())
    # Increment the visitor count
    if 'visited' not in session:
        session['visited'] = True
        visitor_count += 1
        with open(counter_path, 'w') as f:
            f.write(str(visitor_count))
    # Convert visitor count to Persian numeral system
    visitor_count_persian = to_persian_num(visitor_count)

    with open('/var/www/pilapila.net/thetest.html', 'r', encoding='utf-8') as file:      
        html_content = file.read().replace('[Display count here]', visitor_count_persian)
    return render_template_string(html_content)

@app.route('/10_Guess')
def game_10():
    return send_from_directory('/var/www/pilapila.net' , '10.html') 	


@app.route('/15')
def game_15():
    # Serve the 15.html page
    return send_from_directory('/var/www/pilapila.net', '15.html')

@app.route('/sitemap.xml')
def static_from_root():
    return send_from_directory(app.static_folder, request.path[1:])


@app.route('/solve_game', methods=['POST'])
def solve_game():
    data = request.get_json()
    game_state = data['state']

    # Switch all 0s to 1s and 1s to 0s in STATE
    game_state = ''.join(['1' if char == '0' else '0' for char in game_state])

    dimension = int(len(game_state) ** 0.5)
    game_state_matrix = np.array([int(x) for x in game_state]).reshape(dimension, dimension)
    matrices = generate_matrices(dimension)
    A = np.vstack([m.flatten() for m in matrices]).T
    b = game_state_matrix.flatten()
    augmented_matrix = np.hstack([A, b.reshape(-1, 1)])
    rref_matrix = rref(augmented_matrix.tolist())
    solution = extract_solution(rref_matrix, dimension)
# In your Flask app's solve_game function
    return jsonify({'state': ''.join(map(str, solution))})


def generate_matrices(dimension):
    matrices = []
    for i in range(dimension):
        for j in range(dimension):
            matrix = np.zeros((dimension, dimension), dtype=int)
            matrix[i, j] = 1
            if i > 0: matrix[i-1, j] = 1
            if i < dimension-1: matrix[i+1, j] = 1
            if j > 0: matrix[i, j-1] = 1
            if j < dimension-1: matrix[i, j+1] = 1
            matrices.append(matrix)
    return matrices

def rref(matrix):
    m = deepcopy(matrix)
    for row in m:
        for i in range(len(row)):
            row[i] = row[i] % 2

    lead = 0
    rowCount = len(m)
    columnCount = len(m[0])

    for r in range(rowCount):
        if lead >= columnCount:
            return m
        i = r
        while m[i][lead] == 0:
            i += 1
            if i == rowCount:
                i = r
                lead += 1
                if columnCount == lead:
                    return m
        swap_rows(m, i, r)
        for i in range(rowCount):
            if i != r and m[i][lead] == 1:
                m[i] = vector_add(m[i], m[r])
        lead += 1

    back_substitute(m)
    return m


def vector_add(v1, v2):
    return [(v1[i] + v2[i]) % 2 for i in range(len(v1))]

def swap_rows(m, i, j):
    m[i], m[j] = m[j], m[i]

def find_pivot(m, j):
    for i in range(j, len(m)):
        if m[i][j] == 1:
            return i
    return None

def eliminate(m, pivot_row, pivot_col):
    for i in range(pivot_row + 1, len(m)):
        if m[i][pivot_col] == 1:
            m[i] = vector_add(m[i], m[pivot_row])

def back_substitute(m):
    rows, cols = len(m), len(m[0])
    for i in range(rows - 1, -1, -1):
        pivot_col = next((j for j in range(cols) if m[i][j] == 1), None)
        if pivot_col is None:
            continue
        for j in range(i):
            if m[j][pivot_col] == 1:
                m[j] = vector_add(m[j], m[i])

def extract_solution(rref_matrix, dimension):
    solution = [0] * (dimension * dimension)
    for i in range(len(rref_matrix)):
        row = rref_matrix[i]
        if sum(row[:-1]) == 0 and row[-1] == 1:
            return [0] * (dimension * dimension)  # No solution
        if row[i] == 1:
            solution[i] = int(row[-1])  # Assign value from RREF
    return solution

if __name__ == '__main__':
    app.run()

