forked from AliMozdian/Digi-Board
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
1414 lines (1269 loc) · 43.6 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
''' in the name of god
This program is an electrical circuit simulator.
This project has started on January 10, 2019 (10/1/2019 AD)
Authors : Ali Mozdian Fard (Back-end)
Pooya Shams K (Front-end)
'''
# imports
import pygame, sys, json, os
pygame.init()
os.environ ["SDL_VIDEO_CENTERED"] = "1"
#default varaibles
PG_BREAD_BOARD_WINW = 864 # bread board window width
PG_BREAD_BOARD_WINH = 234 # bread board window height
PG_WINW = PG_BREAD_BOARD_WINW + 384 + 100 # pygame window width
PG_WINH = PG_BREAD_BOARD_WINH + 192 # pygame window height
pg_ls_point_poses = []
pg_ls_button_rects = []
pg_ls_button_texts = []
pg_ls_color_rects = []
pg_ls_printed = [None] * 10
all_IC_codes = {"not":"7404", "and":"7408", "or":"7432", "xor":"7486", "xnor":"4077", "nor":"7402", "nand":"7400"}
# R G B
WHITE = (255, 255, 255)
BLACK = ( 0 , 0 , 0 )
RED = (255, 0 , 0 )
GREEN = ( 0 , 255, 0 )
BLUE = ( 0 , 0 , 255)
CYAN = ( 0 , 255, 255)
MAGENTA = (255, 0 , 255)
YELLOW = (255, 255, 0 )
GRAY = (128, 128, 128)
BG_COLOR = WHITE
PG_BUTTON_BG_COLOR = BLACK
PG_BUTTON_FG_COLOR = CYAN
PG_WIRE_COLOR = GRAY
PG_PRINT_FG_COLOR = WHITE
PG_PRINT_BG_COLOR = BLACK
pg_ls_all_colors = [
[RED, GREEN, BLUE],
[CYAN, MAGENTA, YELLOW],
[BLACK, GRAY, WHITE]]
a, f = 0, 0
b, g = 1, 1
c, h = 2, 2
d, i = 3, 3
e, j = 4, 4
#making database(bread board):
#making margin bread board
VOLTAGE = 1
ls_up_posi = [VOLTAGE] * 50
ls_up_nega = [0] * 50
ls_down_posi = [None] * 50
ls_down_nega = [None] * 50
ls_margin_up = [ls_up_nega, ls_up_posi]
ls_margin_down = [ls_down_nega, ls_down_posi]
#making main bread board
ls_main_up = []
for i in range(64):
ls_main_up.append([None]*5)
ls_main_down = []
for i in range(64):
ls_main_down.append([None]*5)
ls_main = [ls_main_up, ls_main_down]
database = [ls_margin_up, ls_main, ls_margin_down]
#end
# LED
ls_LED = []
# Wires
ls_wire = []
# ICs
ls_IC = []
# Command
COMMANDS = []
#start defining functions:
def sync(ls):
'''
This function coordinates the list components,
and return the new list.
'''
global VOLTAGE
if VOLTAGE in ls and 0 in ls:
pg_print(":( short connect :(")
VOLTAGE = 0
else:
for item in range(len(ls)):
if ls[item] == VOLTAGE:
for i in range(len(ls)):
ls[i] = VOLTAGE
break
elif ls[item] == 0:
for i in range(len(ls)):
ls[i] = 0
break
return ls
def detector(A, AB="A"):
A_pos = A[0]
A_leter = A[1]
A_number = int(A[2:])-1
A_pointer = database
if A_pos != "m":
if A_pos == "u":
A_pointer = ls_margin_up
if A_leter == "+":
A_pointer = ls_up_posi
elif A_leter == "-":
A_pointer = ls_up_nega
elif A_pos == "d":
A_pointer = ls_margin_down
if A_leter == "+":
A_pointer = ls_down_posi
elif A_leter == "-":
A_pointer = ls_down_nega
if AB == "A":
A_address = "A_pointer["+str(A_number)+"]"
elif AB == "B":
A_address = "B_pointer["+str(A_number)+"]"
elif A_pos == "m":
A_pointer = ls_main
if A_leter in 'abcde':
A_pointer = ls_main_up
elif A_leter in 'fghij':
A_pointer = ls_main_down
A_pointer = A_pointer[A_number]
A_leter = str(eval(A_leter))
if AB == "A":
A_address = "A_pointer["+A_leter+"]"
elif AB == "B":
A_address = "B_pointer["+A_leter+"]"
return A_pointer, A_address
# wire
def Connect_wire(A, B, color, wire_new):
global database
#A
A_pointer, A_address = detector(A, "A")
#B
B_pointer, B_address = detector(B, "B")
#sync & eval defined
AB_ls = eval('['+A_address+', '+B_address+']')
A_content, B_content = sync(AB_ls)
exec(A_address+' = A_content')
exec(B_address+' = B_content')
if wire_new:
ls_wire.append([A, B, color])
else:
return A_pointer, B_pointer
# LED
def make_LED(anode, cathode, color, rv):# rv : required_voltage
ls_LED.append([anode, cathode, color, rv])
#check functions
def check_OnOff_LED(anode, cathode, rv):# required_voltage
'''
This function checks whether the lamp is lit or not.
If lamp has to be on, return True
else, return False
'''
A_pointer, A_address = detector(anode, "A")
B_pointer, B_address = detector(cathode, "B")
anode = eval(A_address)
cathode = eval(B_address)
if anode == None or cathode == None:
return "OFF"
difference_voltage = anode - cathode
if difference_voltage < rv:
return "OFF"
elif rv <= difference_voltage < float(rv)+.5:
return "ON"
elif float(rv)+.5 <= difference_voltage < rv+1:
return "BURNED"
elif difference_voltage >= rv+1:
return "EXPLODED"
def check_OnOff_IC(Vcc, GND):
A_pointer, A_address = detector(Vcc, "A")
B_pointer, B_address = detector(GND, "B")
Vcc = eval(A_address)
GND = eval(B_address)
if Vcc != None and GND != None and Vcc-GND >= 5:
return True
return False
def check_LED():
if len(ls_LED) > 0:
pg_print("press any key to go to next LED")
pg_print("num | \t", "con | \t", "anode | \t", "cathode | \t", "color | \t", "required_voltage")
pg_getch()
for i, (A, C, c, rv) in enumerate(ls_LED):
condition = check_OnOff_LED(A, C, rv)
pg_print(i+1, "\t\t",condition, "\t\t", A, "\t\t", C, "\t", c, "\t\t", rv)
pg_getch()
def check_wire():
""" outputs all of wires in the board """
if len(ls_wire) > 0:
pg_print("press any key to go to next wire")
pg_print("num " + (" ")*len(str(len(ls_wire))) + " : " + "\t" + "A" + "\t" + "B")
i = 0
for A, C, color in ls_wire:
i += 1
pg_print("wire "+str(i)+" : "+"\t"+A+(" "*(8-(len(A))+3))+C)
pg_getch()
def check_IC():
""" checks all ICs"""
global ls_IC
if len(ls_IC) > 0:
pg_print("press any key to go to next IC")
pg_print("num | \t", "Vcc | \t", "con | \t", "code | \t")
pg_getch()
for i, IC in enumerate(ls_IC):
Vcc = IC[14]
GND = IC[7]
pg_print(i+1, "\t\t", Vcc, "\t", check_OnOff_IC(Vcc, GND), "\t", IC[0])
pg_getch()
def check_point(A):
A_pointer, A_address = detector(A)
return eval(A_address)
# save & open function
def save(name):
dct = {"LED": ls_LED, "wire": ls_wire, "IC": ls_IC, "commands": COMMANDS, "voltage": VOLTAGE}
name += '.dgb'
with open(name, 'w') as s:
s.write(json.dumps(dct, indent=2))
del dct
def open_file(name):
global ls_wire, ls_LED, ls_IC, COMMANDS, VOLTAGE
name += '.dgb'
with open(name, 'r') as o:
dct = json.loads(o.read())
ls_LED = dct["LED"]
ls_wire = dct["wire"]
ls_IC = dct["IC"]
COMMANDS = dct["commands"]
VOLTAGE = dct["voltage"]
del dct
# ctrl+Z
def del_item(i=-1):
global COMMANDS, ls_LED, ls_wire, ls_IC
if COMMANDS[i] in ls_LED:
i2 = ls_LED.index(COMMANDS[i])
if ls_LED[i2] == COMMANDS[i]:
COMMANDS.pop(i)
ls_LED.pop(i2)
elif COMMANDS[i] in ls_wire:
i2 = ls_wire.index(COMMANDS[i])
if ls_wire[i2] == COMMANDS[i]:
COMMANDS.pop(i)
ls_wire.pop(i2)
elif COMMANDS[i] in ls_IC:
i2 = ls_IC.index(COMMANDS[i])
if ls_IC[i2] == COMMANDS[i]:
COMMANDS.pop(i)
ls_IC.pop(i2)
# restart
def make_defaults(A, B, color):
Connect_wire(A, B, color, True)
COMMANDS.append(ls_wire[-1])
refresh()
def restart():
global ls_LED, ls_wire, ls_IC, COMMANDS, VOLTAGE
ls_LED = []
ls_wire = []
ls_IC = []
COMMANDS = []
VOLTAGE = 1
pg_clear()
pg_print("\t\tWelcome to digi-board!\n\n")
make_defaults("u+50", "d+50", RED)
make_defaults("u-50", "d-50", BLUE)
# IC
def make_IC(p_vcc, code):
global ls_IC
ls = [code]
n = int(p_vcc[2:])
for i in range(7):
ls.append('mf'+str(n+i))
for i in range(6, -1, -1):
ls.append('me'+str(n+i))
ls_IC.append(ls)
# main gates
def gate_and(A, B):
return A and B
def gate_not(A):
if A == None:
return None
if A == 0:
return VOLTAGE
return 0
def gate_or(A, B):
if A == None or B == None:
return None
return A or B
# gates
def gt_7408(A, B):
A_pointer, A_address = detector(A, "A")
B_pointer, B_address = detector(B, "B")
A = eval(A_address)
B = eval(B_address)
return gate_and(A, B)
def gt_7404(A):
A_pointer, A_address = detector(A, "A")
A = eval(A_address)
return gate_not(A)
def gt_7432(A, B):
A_pointer, A_address = detector(A, "A")
B_pointer, B_address = detector(B, "B")
A = eval(A_address)
B = eval(B_address)
return gate_or(A, B)
def gt_7400(A, B):
return gate_not(gt_7408(A, B))
def gt_7402(A, B):
return gate_not(gt_7432(A, B))
def gt_7486(A, B):
A_pointer, A_address = detector(A, "A")
B_pointer, B_address = detector(B, "B")
A = eval(A_address)
B = eval(B_address)
return gate_or(gate_and(gate_not(A), B), gate_and(A, gate_not(B)))
def gt_4077(A, B):
return gate_not(gt_7486(A, B))
def ic_not(ls):
A_pointer, A_address = detector(ls[7], "A")
B_pointer, B_address = detector(ls[14], "B")
GND = eval(A_address)
Vcc = eval(B_address)
if Vcc == None or GND == None:
return
if Vcc - GND >= 5:
for i in range(1, 6, 2):
A_pointer, A_address = detector(ls[i+1])
exec(A_address+' = gt_7404(ls['+str(i)+'])')
for i in range(13, 8, -2):
A_pointer, A_address = detector(ls[i-1])
exec(A_address+' = gt_7404(ls['+str(i)+'])')
def ic_no_not(ls):
A_pointer, A_address = detector(ls[7], "A")
B_pointer, B_address = detector(ls[14], "B")
GND = eval(A_address)
Vcc = eval(B_address)
if Vcc == None or GND == None:
return
if Vcc - GND >= 5:
A_pointer, A_address = detector(ls[3])
exec(A_address+'= gt_'+ls[0]+'(ls[1], ls[2])')
A_pointer, A_address = detector(ls[6])
exec(A_address+'= gt_'+ls[0]+'(ls[4], ls[5])')
A_pointer, A_address = detector(ls[8])
exec(A_address+'= gt_'+ls[0]+'(ls[10], ls[9])')
A_pointer, A_address = detector(ls[11])
exec(A_address+'= gt_'+ls[0]+'(ls[13], ls[12])')
# refresh
def refresh_ICs():
global ls_IC
for i in ls_IC:
if i[0] != "7404":
ic_no_not(i)
else:
ic_not(i)
def pg_refresh():
pygame.display.update()
def empty_board():
for i in range(64):
ls_main_up[i] = [None] * 5
ls_main_down[i] = [None] * 5
for i in range(50):
ls_up_posi[i] = VOLTAGE
# margin down
for i in range(2):
for j in range(50):
database[2][i][j] = None
def refresh_wires():
for ii in range(len(ls_wire)):
for A, B, color in ls_wire:
ls_A, ls_B = Connect_wire(A, B, color, False)
ls_A[:] = sync(ls_A)
ls_B[:] = sync(ls_B)
for i in range(64):
ls_main_up[i] = sync(ls_main_up[i])
ls_main_down[i] = sync(ls_main_down[i])
ls_down_posi[:] = sync(ls_down_posi)
ls_down_nega[:] = sync(ls_down_nega)
def refresh():
empty_board()
for i in range(len(ls_IC)):
refresh_wires()
refresh_ICs()
refresh_wires()
pg_refresh()
# guide function
def guide():
pg_print(''' WELCOME TO DIGI-BOARD GUIDE
press any key to go to next tip.''')
pg_getch()
pg_print(" 1- voltage (number): This tool can change the voltage of bread board")
pg_getch()
pg_print(''' 2- planting tools:
2.1- LED: This tool can plant a LED on your bread board
2.2- wire: This tool can connect a wire on your bread board''')
pg_getch()
pg_print(''' 3- check tools:
3.1- check voltage: This tool says how much is the voltage in your bread board.(measured in volt)
3.2- check LED: This tool says about all of LED.
(anodes pos, cathodes pos, color, required voltage)
3.3- check wire: This tool says about anodes' & cathods' pos of all of wire.
3.4- check (point): This tool says about the points content.''')
pg_getch()
pg_print(''' 4- system tools:
4.1- screenshot: This tool can take a picture.
4.2- save: This tool can save your new board.
4.3- open: This tool can open your saved board.
4.4- rename: This tool can change name of your new board''')
pg_getch()
pg_print(''' 5- deleting tools:
5.1- z: This tool's mean 'Ctrl+Z'.
5.2- del: This tool can delete an item. (like LED or wire)
5.3- restart: This tool can restart your board & delete all of your LEDs and wires''')
pg_getch()
pg_print(" 6- refresh: This tool refreshs your board.")
pg_getch()
pg_print(" 7- clear: This tool can clear the terminal")
pg_getch()
pg_print(" 8- guide: this tool can declare to you, the tools")
pg_getch()
pg_print(" 9- quit: This tool closes your board.")
pg_getch()
pg_print("10- cod: This tool is just for debugging the programme by programmers of digi-board (Ali & Pooya)")
pg_getch()
#### graphical functions ----------------------------------------------------------------------------------------------------
#### main window
def pg_surface():
""" makes the pygame surface """
global DISPLAYSURF
DISPLAYSURF = pygame.display.set_mode((PG_WINW, PG_WINH))
pygame.display.set_caption("digi-board")
icon = pygame.image.load('digi-board.png')
pygame.display.set_icon(icon)
DISPLAYSURF.fill(BG_COLOR)
## helping functions
# writing on Surfaces
def pg_write(win, text, pos = (0, 0), file="freesanasbold.ttf", size=32, antialiased=True, bg_color=None, fg_color=(255, 255, 255), side="center"):
""" writes with pygame in a particular point of surface"""
fontobj = pygame.font.SysFont(file, size)
textsurface = fontobj.render(text, antialiased, fg_color, bg_color)
textrect = textsurface.get_rect()
if side == "center":
textrect.center = pos
elif side == "topleft":
textrect.topleft = pos
win.blit(textsurface, textrect)
# cropping surface
def pg_cut_rect_from_surface(surface, rect):
return surface.subsurface(rect)
# distance
def pg_distance(x1, y1, x2, y2):
return ((x2 - x1)**2 + (y2 - y1)**2)**.5
# onRect
def pg_on_rect(rect, x, y):
""" checks if one position is on one rect or not"""
if rect[0] < x < rect[0]+rect[2] and rect[1] < y < rect[1]+rect[3]:
return True
return False
def pg_on_circle(x1, y1, x2, y2, r):
""" checks if one point is on one circle or not """
if pg_distance(x1, y1, x2, y2) < r:
return True
return False
# on line
def pg_on_line(ap, bp, cp, er=3):
x1, y1 = ap
x2, y2 = bp
x3, y3 = cp
bx, kx = max(x1, x2), min(x1, x2)
by, ky = max(y1, y2), min(y1, y2)
if kx <= x3 <= bx and ky <= y3 <= by:
dx = x2 - x1
dy = y2 - y1
if dx == 0:
if abs(x1-x3)<er:
return True
return False
elif dy == 0:
if abs(y1-y3)<er:
return True
return False
else:
m = dy / dx
b = y1 - m * x1
y = m*x3+b
if abs(y-y3) < er:
return True
return False
# float -> int
def pg_float_int(f):
""" returns int(f) if possible """
if f%1 == 0:
return int(f)
return f
# decrease color
def pg_decrease_color(color):
""" decrease the colors brightness """
r, g, b = color
color = [r, g, b]
for i in range(len(color)):
if color[i] < 120:
color[i] = 0
continue
color[i] -= 100
return tuple(color)
# change the name
def pg_change_name(name):
pygame.display.set_caption('digi-board: ' + name)
### Making listes
## point poses
def pg_Make_point_poses():
""" makes an empty list of points poses in the
pygame surface to be filled later in other functions
(and also global the list)"""
global pg_ls_point_poses
pg_ls_up_posi = [None] * 50
pg_ls_up_nega = [None] * 50
pg_ls_down_posi = [None] * 50
pg_ls_down_nega = [None] * 50
pg_ls_margin_up = [pg_ls_up_posi, pg_ls_up_nega]
pg_ls_margin_down = [pg_ls_down_posi, pg_ls_down_nega]
pg_ls_main_up = []
for i in range(64):
pg_ls_main_up.append([None]*5)
pg_ls_main_down = []
for i in range(64):
pg_ls_main_down.append([None]*5)
pg_ls_main = [pg_ls_main_up, pg_ls_main_down]
pg_ls_point_poses = [pg_ls_margin_up, pg_ls_main, pg_ls_margin_down]
## buttons texts
def pg_Make_button_texts():
global pg_ls_button_texts
pg_ls_button_texts = [
["voltage"],
["wire", "LED", ],
["not", "and", "or", "xor", "xnor", "nor", "nand"],
["check:", "voltage", "LED", "wire", "IC", "point"],
["screenshot", "save", "open", "rename"],
["button background color", "button foreground color"],
["terminal background color", "terminal foreground color"],
["undo", "delete", "restart"],
["refresh", "clear"],
["help", "credits", "quit"]]
return pg_ls_button_texts
## buttons rects
def pg_Make_button_rects():
global pg_ls_button_rects
texts = pg_Make_button_texts()
for i in texts:
pg_ls_button_rects.append([None]*len(i))
return pg_ls_button_rects
## color rects
def pg_Make_color_rects():
global pg_ls_color_rects, pg_ls_all_colors
for i in pg_ls_all_colors:
pg_ls_color_rects.append([None]*len(i))
return pg_ls_color_rects
### drawing main parts on the window
## printed texts
def pg_print(*value, sep=" ", end="\n", length=10):
""" uses a little space to write the printed things"""
global pg_ls_printed
text = ""
for t in value:
text += str(t) + sep
text += end
text = text.replace("\t", " ")
text = text.split("\n")
pg_ls_printed.extend(text)
if len(pg_ls_printed) > length:
pg_ls_printed = pg_ls_printed [-length-1:-1]
pg_draw_printed(DISPLAYSURF, 0, PG_BREAD_BOARD_WINH, PG_BREAD_BOARD_WINW, PG_WINH, None, PG_PRINT_FG_COLOR)
pygame.display.update()
return pg_ls_printed
def pg_draw_printed(win, x, y, width, height, bg, fg):
""" draws all printed text in the window """
global pg_ls_printed
m = len(pg_ls_printed)
w = width - x - 8
h = (height - y) // m
win.fill(PG_PRINT_BG_COLOR, (x, y, width-x, height-y))
def write_nth_line(win, x, y, w, h, bg, fg, n, m, text):
""" writes the text in the nth line of m ones """
x += 4
y += 4 + h*n
pg_write(win, text, pos=(x, y), size=25, bg_color=bg, fg_color=fg, side="topleft")
for i, text in enumerate(pg_ls_printed):
write_nth_line(win, x, y, w, h, bg, fg, i, m, text)
def pg_clear(length=10):
global pg_ls_printed
pg_ls_printed = [""] * length
## buttons
def pg_draw_buttons (win, x, y, width, height, first=False):
""" this function ``just`` draws the buttons on
the right side of the bread board """
global pg_ls_button_texts
def n_rect_write(win, x, y, width, height, n, m, l, lis, bg, fg):
""" draws n rects in the m th row of
l ones and writes the lis on them"""
w = (width - x) // n
h = height // l
y += (h+1)*m
for i in range(n):
xx = x+((w+1)*i)
r = (xx, y, w-2, h)
pygame.draw.rect(win, bg, r)
pg_write(win, lis[i], pos=(xx+w//2, y+h//2), size=24, antialiased=False, fg_color=fg)
if first:
pg_ls_button_rects [m][i] = r
ll = len(pg_ls_button_texts)
for i in range(ll):
n_rect_write(win, x, y, width, height, len(pg_ls_button_texts[i]), i,
ll, pg_ls_button_texts[i], PG_BUTTON_BG_COLOR,
PG_BUTTON_FG_COLOR)
## colors pool ;p
def pg_draw_color_pool(win, x, y, width, height, first=False):
""" draws the colors pool in a specific rect """
global pg_ls_all_colors, pg_ls_color_rects
width, height = width-x, height-y
def n_rect(win, x, y, width, height, n, m,colorlis, first=first):
""" draws the nth line of m lines of rects of color """
ll = len(colorlis)
w = (width-8) // ll
h = (height-8-2*m) // m
y += 4 + (h+2)*n
x += 4 - (2+w)
for i in range(ll):
x += 2+w
r = (x, y, w, h)
pygame.draw.rect(win, colorlis[i], r)
pygame.draw.rect(win, BLACK, r, 2)
if first:
pg_ls_color_rects[n][i] = r
#
ll = len(pg_ls_all_colors)
for i, lis in enumerate(pg_ls_all_colors):
n_rect(win, x, y, width, height, i, ll, lis)
## LEDs
def pg_draw_LEDs(win):
for LED in ls_LED:
color = LED[2]
condition = check_OnOff_LED(*LED[:2], LED[3])
if condition == "OFF":
color = pg_decrease_color(color)
elif condition == "BURNED":
color = BLACK
elif condition == "EXPLODED":
color = (127, 127, 127)
x1, y1 = pg_point_pos(LED[0])
x2, y2 = pg_point_pos(LED[1])
x1, y1 = x1+4, y1+4
x2, y2 = x2+4, y2+4
pos = x1+(x2-x1)//2, y1+(y2-y1)//2
pygame.draw.line(win, color, (x1, y1), (x2, y2), 2)
pygame.draw.circle(win, color, pos, 10)
## wires
# one wire
def pg_draw_wire(win, A, B, color):
""" draws one given wire between two points (A, B)"""
A, B = map(pg_point_pos, (A, B))
A = A[0]+4, A[1]+4
B = B[0]+4, B[1]+4
pygame.draw.line(win, color, A, B, 2)
# all wires
def pg_draw_wires(win):
""" draws all of the wires in the board """
for A, B, color in ls_wire:
pg_draw_wire(win, A, B, color)
Connect_wire(A, B, color, False)
## IC
# one
def pg_draw_IC(win, IC):
""" draws one ic """
p_GND = IC[14]
code = IC[0]
x, y = pg_point_pos(p_GND)
w = 12*7
h = 13
rect = (x, y+5+8, w-4, h)
pygame.draw.rect(win, BLACK, rect)
pg_write(win, code, (rect[0]+rect[2]//2, rect[1]+rect[3]//2), size=16, antialiased=True, fg_color=WHITE, side="center")
#pygame.draw.arc(win, RED, (x, y+5+8 + 2, 8, 8), 180, 270)
for i in range(1, 8):
xi, yi = pg_point_pos(IC[i])
pygame.draw.line(win, GRAY, (xi+4, yi+4), (xi+4, yi-4))
for i in range(8, 15):
xi, yi = pg_point_pos(IC[i])
pygame.draw.line(win, GRAY, (xi+4, yi+4), (xi+4, yi+4+8))
# all
def pg_draw_ICs(win):
""" draws all ICs """
for i in range(len(ls_IC)):
pg_draw_IC(win, ls_IC[i])
## bread board
def pg_draw_board(win, width=PG_BREAD_BOARD_WINW, height=PG_BREAD_BOARD_WINH, first=False):
""" draws the board on pygame surface """
# dot_width = 8
# dot_gap = 4
# width_max_dots = 64
# width_min_dots = 50
# height_dots = 14
##########################
# to be changed basicly
##########################
global pg_ls_point_poses
pygame.draw.rect(win, BLACK, (4, 4, width-8, height-8), 2)
def pg_margin(x, y, cycle, first=first):
for i in range(2):
for j in range(10):
for k in range(5):
color = BLACK
dot = database[cycle][i][j*5+k]
if dot == VOLTAGE:
color = RED
elif dot == 0:
color = BLUE
if cycle == 0 and j==0 and k == 0:
color = BLACK
xx, yy = ((j * 6 + k) * 12) + x, i * 12 + y
pygame.draw.line(win, color, (xx, yy+4), (6, yy+4))
xx, yy = ((j*6+k)*12)+x, i*12+y
pygame.draw.rect(win, color, (xx, yy, 8, 8))
if first:
pg_ls_point_poses[cycle][i][j*5+k] = (xx, yy)
def pg_main(x, y, lis, cycle, first=first):
for i in range(64):
for j in range(5):
if i == 0:
pg_write(win, lis[j], pos=(i*12+x-6, j*12+y+4), size=16, fg_color=BLACK)
if cycle == 0 and j == 0 and ((i+1)%5 == 0 or i == 0 or i == 63):
pg_write(win, str(i+1), pos=(i*12+x+4, j*12+y-4), size=16, fg_color=BLACK)
if cycle == 1 and j == 4 and ((i+1)%5 == 0 or i == 0 or i == 63):
pg_write(win, str(i+1), pos=(i*12+x+4, j*12+y+14), size=16, fg_color=BLACK)
p = database[1][cycle][i][j]
color = BLACK
if p == VOLTAGE:
color = RED
elif p == 0:
color = BLUE
elif p == None:
color = BLACK
pygame.draw.rect(win, color, (i*12+x, j*12+y, 8, 8))
if first:
pg_ls_point_poses[1][cycle][i][j] = (i*12+x, j*12+y,)
pg_margin((width-696)//2, 8, 0)
pg_margin((width-696)//2, height-(8+20), 2)
pg_main((width-768)//2, 24+8+16 , "abcde", 0)
pg_main((width-768)//2, height-(24+8+16 + 60), "fghij", 1)
pg_draw_LEDs(win)
pg_draw_wires(win)
pg_draw_ICs(win)
### inputting and helping in input functions
## help
# point
def pg_point_pos_index(A):
A_pos = A[0].lower()
A_letter = A[1].lower()
A_number = int(A[2:])-1
pos = "umd".index(A_pos)
letter = A_letter
num = A_number
if A_pos == "m":
if letter in "abcde":
return pos, 0, num, "abcde".index(letter)
elif letter in "fghij":
return pos, 1, num, "fghij".index(letter)
elif A_pos in "ud":
if letter in "-+":
return pos, "-+".index(letter), num
def pg_point_pos(A):
global pg_ls_point_poses
A_pos = A[0]
if A_pos == "m":
a, b, c, d = pg_point_pos_index(A)
return pg_ls_point_poses [a][b][c][d]
elif A_pos in "ud":
a, b, c = pg_point_pos_index(A)
return pg_ls_point_poses[a][b][c]
def pg_convert_index_to_board_language(indexes):
if indexes == None:
return None
A_pos = "umd"[indexes[0]]
if A_pos == "m":
A_letter = "abcdefghij"[indexes[3]+(indexes[1]*5)]
A_num = indexes[2]
else:
A_letter = "-+"[indexes[1]]
A_num = indexes[2]
return A_pos+A_letter+str(A_num+1)
def pg_clicked_point_index(pos):
""" checks if a clicked point in the surface is
a point in the board or not.
and if so, it returns the adress by the indexes """
x, y = pos
for m in [pg_ls_point_poses[0], pg_ls_point_poses[2]]: # m is the margin
for q in m: # q is the positive or negative part of margins
for p in q: # p is the position
if pg_on_rect(tuple(p)+(8, 8), x, y):
return [pg_ls_point_poses[0], None, pg_ls_point_poses[2]].index(m), m.index(q), q.index(p)
for s in pg_ls_point_poses[1]: # s is the side in main (main_up or main_down)
for row in s: # row has 64 cases
for p in row:
if pg_on_rect(tuple(p)+(8, 8), x, y):
return 1, pg_ls_point_poses[1].index(s), s.index(row), row.index(p)
return None # returns None if the clicked point is not on the points on the surface
## get
# clicked point
def pg_get_clicked_point():
""" returns the pygame clicked point pos """
global pg_ls_button_rects
while True:
pg_reset_screen()
for e in pygame.event.get():
if e.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif e.type == pygame.MOUSEBUTTONDOWN:
return e.pos
# button
def pg_get_button(pos):
""" this function checks if one
clicked point is button or not
and returns the button"""
global pg_ls_button_rects
global pg_ls_button_texts
for i, row in enumerate(pg_ls_button_rects):
for j, rect in enumerate(row):
if pg_on_rect(rect, *pos):
if i == 3:
if pg_ls_button_texts[i][j] != "check:":
return "check "+ pg_ls_button_texts[i][j]
return "check"
return pg_ls_button_texts[i][j]
return None # returns None if the clicked point is not a button
# color
def pg_get_color(pos):
""" gets the given color by pos returns
None if there is no color clicked """
global pg_ls_all_colors, pg_ls_color_rects
for i, row in enumerate(pg_ls_color_rects):
for j , rect in enumerate(row):
if pg_on_rect(rect, *pos):
return pg_ls_all_colors[i][j]
return None # so there is no color clicked
# string inputting
def pg_get_str_input(default_text=""):
""" catches everything that user writes and yields it """
answer = default_text
yield answer
answer = pg_getch()
if answer == "\r":
return answer
yield answer
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif e.type == pygame.KEYDOWN:
u = e.unicode
if u == "\r":
return answer
elif u == "\b":
answer = answer[:-1]
yield answer
else:
answer += u
yield answer
# integer inputting
def pg_get_int_input(default_text="0"):
""" catches every number that user writes and yields it """
nums = "1234567890"
if default_text.isnumeric():
answer = default_text
else:
answer = "0"
yield answer
answer = pg_getnumch()
if answer == "\r":
return answer
yield answer
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
pygame.quit()
sys.exit()
if e.type == pygame.KEYDOWN:
u = e.unicode
if u == "\r":
return answer
elif u == "\b":
answer = answer[:-1]
yield answer
elif u in nums:
answer += u
yield answer
# float(decimal) inputting
def pg_get_float_input(default_text="0.0"):
""" catches every number or '.' that user writes and yields it """
nums = "1234567890."
if default_text.isdecimal():
answer = default_text
else: