mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some update
This commit is contained in:
parent
dcb784a7a8
commit
a1797869db
@ -89,3 +89,21 @@ class array2d(Generic[T]):
|
||||
self.n_cols = other.n_cols
|
||||
self.n_rows = other.n_rows
|
||||
self.data = other.data.copy()
|
||||
|
||||
# for cellular automata
|
||||
def count_neighbors(self, value) -> array2d[int]:
|
||||
new_a: array2d[int] = array2d(self.n_cols, self.n_rows)
|
||||
for j in range(self.n_rows):
|
||||
for i in range(self.n_cols):
|
||||
count = 0
|
||||
count += int(self.is_valid(i-1, j-1) and self[i-1, j-1] == value)
|
||||
count += int(self.is_valid(i, j-1) and self[i, j-1] == value)
|
||||
count += int(self.is_valid(i+1, j-1) and self[i+1, j-1] == value)
|
||||
count += int(self.is_valid(i-1, j) and self[i-1, j] == value)
|
||||
count += int(self.is_valid(i+1, j) and self[i+1, j] == value)
|
||||
count += int(self.is_valid(i-1, j+1) and self[i-1, j+1] == value)
|
||||
count += int(self.is_valid(i, j+1) and self[i, j+1] == value)
|
||||
count += int(self.is_valid(i+1, j+1) and self[i+1, j+1] == value)
|
||||
new_a[i, j] = count
|
||||
return new_a
|
||||
|
||||
|
@ -31,6 +31,14 @@ struct Array2d{
|
||||
return 0 <= col && col < n_cols && 0 <= row && row < n_rows;
|
||||
}
|
||||
|
||||
PyObject* _get(int col, int row){
|
||||
return data[row * n_cols + col];
|
||||
}
|
||||
|
||||
void _set(int col, int row, PyObject* value){
|
||||
data[row * n_cols + col] = value;
|
||||
}
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type){
|
||||
vm->bind(type, "__new__(cls, *args, **kwargs)", [](VM* vm, ArgsView args){
|
||||
Type cls = PK_OBJ_GET(Type, args[0]);
|
||||
@ -71,7 +79,7 @@ struct Array2d{
|
||||
int col = CAST(int, args[1]);
|
||||
int row = CAST(int, args[2]);
|
||||
if(!self.is_valid(col, row)) return args[3];
|
||||
return self.data[row * self.n_cols + col];
|
||||
return self._get(col, row);
|
||||
});
|
||||
|
||||
vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
|
||||
@ -82,7 +90,7 @@ struct Array2d{
|
||||
if(!self.is_valid(col, row)){
|
||||
vm->IndexError(_S('(', col, ", ", row, ')', " is not a valid index for array2d(", self.n_cols, ", ", self.n_rows, ')'));
|
||||
}
|
||||
return self.data[row * self.n_cols + col];
|
||||
return self._get(col, row);
|
||||
});
|
||||
|
||||
vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1, PyObject* _2){
|
||||
@ -93,18 +101,16 @@ struct Array2d{
|
||||
if(!self.is_valid(col, row)){
|
||||
vm->IndexError(_S('(', col, ", ", row, ')', " is not a valid index for array2d(", self.n_cols, ", ", self.n_rows, ')'));
|
||||
}
|
||||
self.data[row * self.n_cols + col] = _2;
|
||||
self._set(col, row, _2);
|
||||
});
|
||||
|
||||
vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0){
|
||||
Array2d& self = PK_OBJ_GET(Array2d, _0);
|
||||
List t(self.n_rows);
|
||||
List row(self.n_cols);
|
||||
for(int i = 0; i < self.n_rows; i++){
|
||||
for(int j = 0; j < self.n_cols; j++){
|
||||
row[j] = self.data[i * self.n_cols + j];
|
||||
}
|
||||
t[i] = VAR(row); // copy
|
||||
for(int j = 0; j < self.n_rows; j++){
|
||||
for(int i = 0; i < self.n_cols; i++) row[i] = self._get(i, j);
|
||||
t[j] = VAR(row); // copy
|
||||
}
|
||||
return vm->py_iter(VAR(std::move(t)));
|
||||
});
|
||||
@ -180,6 +186,30 @@ struct Array2d{
|
||||
}
|
||||
return vm->True;
|
||||
});
|
||||
|
||||
// for cellular automata
|
||||
vm->bind(type, "count_neighbors(self, value) -> array2d[int]", [](VM* vm, ArgsView args){
|
||||
Array2d& self = PK_OBJ_GET(Array2d, args[0]);
|
||||
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm));
|
||||
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
|
||||
new_array.init(self.n_cols, self.n_rows);
|
||||
PyObject* value = args[1];
|
||||
for(int j = 0; j < new_array.n_rows; j++){
|
||||
for(int i = 0; i < new_array.n_cols; i++){
|
||||
int count = 0;
|
||||
count += self.is_valid(i-1, j-1) && vm->py_eq(self._get(i-1, j-1), value);
|
||||
count += self.is_valid(i, j-1) && vm->py_eq(self._get(i, j-1), value);
|
||||
count += self.is_valid(i+1, j-1) && vm->py_eq(self._get(i+1, j-1), value);
|
||||
count += self.is_valid(i-1, j) && vm->py_eq(self._get(i-1, j), value);
|
||||
count += self.is_valid(i+1, j) && vm->py_eq(self._get(i+1, j), value);
|
||||
count += self.is_valid(i-1, j+1) && vm->py_eq(self._get(i-1, j+1), value);
|
||||
count += self.is_valid(i, j+1) && vm->py_eq(self._get(i, j+1), value);
|
||||
count += self.is_valid(i+1, j+1) && vm->py_eq(self._get(i+1, j+1), value);
|
||||
new_array._set(i, j, VAR(count));
|
||||
}
|
||||
}
|
||||
return new_array_obj;
|
||||
});
|
||||
}
|
||||
|
||||
void _gc_mark() const{
|
||||
|
@ -99,3 +99,8 @@ assert A().width == 2
|
||||
assert A().height == 4
|
||||
assert A().numel == 8
|
||||
assert A().get(0, 0, default=2) == 0
|
||||
|
||||
# test alive_neighbors
|
||||
a = array2d(3, 3, default=0)
|
||||
a.count_neighbors(0) == a
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user