https://gall.dcinside.com/mgallery/board/view/?id=factorio&no=55620

과거 N틱동안의 누적량 저장해서 평균 구하는 회로벨트에서 아이템이 지나가는 양 등 생산량에 관련된 값을 측정하고 싶은 경우가 있음이때 한 틱의 결과만 얻어서 사용한다면 결과가 매우 들쭉날쭉해서 써먹기 힘듬따라서 과거의 여러 틱의 결과들을 합산해 그 평균을 사용하게gall.dcinside.com


윗 링크의 구현체




바로 밑 글을 레퍼런스하는 것도 좀 웃기긴한데

https://gall.dcinside.com/mgallery/board/view/?id=factorio&no=55686

바닐라용 모든 신호 리스트아이템 203개["wooden-chest","iron-chest","steel-chest","storage-tank","transportgall.dcinside.com


이걸 만들자마자 바로 써먹었다



전체적인 구조

모든 신호를 순환하기 위한 일정신호조합기의 배꼽이 좀 크다

그 외에는 꽤 간단하게 나온듯?







신호발생기부분


왼쪽의 신호발생기부분에서는 최대 293종류의 신호를 발생시킬 수 있도록 모든신호에 대하여 넘버링이 되어있다

다만 원래 점신호는 259번을 할당받았지만 오른쪽의 루프 회로에서 점신호를 사용하기 때문에 꼬이는 것을 막기위해 일정신호조합기에서는 점신호를 내보내지 않는다.


1번셀에서는 1부터 293까지 점신호를 루프시키고 이 값은 2번셀로 들어간다


2번셀에서는 점신호와 같은 값을 가지는 신호만 통과시키고 출력값은 1로 고정한다.

예를들어 점신호가 7이라면 같은 값을 가지는 파란벨트만 통과해서 출력이 1이 나갈 것이다

다만 여기서 노란별=점신호를 하고 있기때문에 노란별에는 점신호 또한 매칭이 되어서 점신호도 출력1로 나가게 된다

이를 막기 위해 4번 상수조합기에서 점신호를 -1로 내보내주어 서로 상쇄시킨다


한편 3번셀에서는 원래 점신호의 할당번호인 259에 대하여 처리를 해주고 있다. 점신호 입력이 259일때는 2번 셀에서는 출력을 내보내지 않겠지만 이 때는 3번회로가 점신호를 1 출력시켜주게 된다.


만약 주기를 293틱보다 줄이고 싶다면 1번 셀을 수정하면 된다.


이렇게 발생된 신호는 아래의 회로 입력으로 들어가게 된다.





7번셀은 메모리다 0이상의 값이 들어오면 그걸 저장할것이고 0미만의 값이 들어오면 그 값은 0으로 초기화시킨다


1번셀에는 위에서 만든 신호발생기에서 하나의 신호가 선정되어 이곳으로 입력된다. 이 값에 -21억 어쩌고를 곱하고 그 값이 7번셀로 들어가고 있는데 예를들어 'A'신호가 입력이 되었다면 7번셀에 A값이 어떻게 저장되어있든간에 그 값을 초기화 시킬수 있다.


1번셀에 들어오는 신호는 마찬가지로 2번셀에도 들어간다

여기선 노란별+0=노란별을 하고 있는데 이건 그냥 딜레이 셀이다. 7번셀의 값을 날려버린 후 그 다음틱에 값을 저장하여야 하기 때문에 그를 위한 딜레이셀


3번, 4번셀에서는 벨트에서 읽은 값 N이 들어온다. 이걸 점신호와 정보신호로 추상화하고 있음(벨트에 무슨아이템이 오더라도 동작하기 위하여)

점신호는 그냥 양의 값이 그대로 들어오게했고 정보신호는 이걸 음의 값으로 바꿔주고있다


5번셀에서는 점신호*노란별=노란별을 해주고있다.

신호발생기에서 만약 'A'신호가 들어오고 있었다면 'A신호'=1, '점신호'='벨트에서 읽은 값 N'이기 때문에 출력으로 'A신호'='벨트에서 읽은 값이 된다'

이 값은 7번셀로 가게되는데, 1번셀에 의하여 직전틱에서 'A신호'에 대한 이전 값은 날아간 상태이기 때문에 깔끔하게 갱신값을 저장할 수 있다.


한편 5번셀에서는 'A신호'*'점신호'를 해줌과 동시에 '점신호'*'점신호'도 하고 있다.(노란별*점신호 이기에)

그렇기 때문에 별다른 처리를 하지 않는다면 출력으로 '점신호'=N*N 값 또한 7번 메모리셀로 흘러들어가 이상한 값을 저장하게 되어버린다.

따라서 이걸 막기위해 4번셀이 존재한다. 4번셀에서는 '점신호'*'정보신호'를 해주고 있는데 즉 N*-N을 해서 -N*N이 출력으로 나온다.

이게 5번셀에서 나오는 N*N과 상쇄되기 때문에 7번에는 점신호가 흘러들어가지 않고 깔끔하게 의도한 값만 들어가게 된다.


8번셀에서는 60을 곱한다(1초는 60틱이니깐)

한편 곱함과 동시에 출력을 점신호로 통일하였기 때문에 모든 메모리 값을 다 합산한다.


9번셀에서는 (신호주기-1)로 값을 나눠준다

메모리는 최대 293개의 값까지 저장할 수 있긴하지만 그중에 딱 한 셀은 1번셀에 의하여 초기화가 된 직후일 것이기 때문에 (신호주기-1)로 나누어 주어야 한다.




최대 293틱까지 가능하긴하지만 실제로 실험을 해보니 이건 뭔가 반응이 너무 굼뜨다는 생각이 좀 들었다

역시 무조건 많다고 좋은건 아닌듯


그리고 실험하면서 일부 주기에 대해서는 출력값이 상당히 출렁거리는 것을 볼 수 있었는데 이 꼬라지를 보기 싫다면 평균내기 위한 샘플을 8의 배수로 하는게 좋다

노란벨트가 초당15개 옮기는데


60틱당 15개

40틱당 10개

8틱당 2개

4틱당 1개


4틱당 1개라는건 바꿔말하면 4틱당 반줄반줄이 각각 0.5개라는 뜻이다. 이래서 0으로 카운팅될때도 있고 1로 카운팅될때도 있어서 값이 출렁거리게 됨

8틱당 1개라는건 8틱마다 반줄이 옮길 수 있는 아이템의 갯수가 정확히 정수배가 되기 때문에 출렁거리는 현상이 사라지게 된다


오랜만에 회로가지고 놀아서 재밌었다


https://factoriobin.com/post/FDs1jtRw

이거 글 수정전에 올린건데 이건 쓰지마




https://factoriobin.com/post/ge5Vt2W_

이건 item-unknown, fluid-unknown, signal-unknown이 없는 버전 (최대 290까지)



https://factoriobin.com/post/RG7H3XW7

이건 item-unknown, fluid-unknown, signal-unknown이 있는 버전 (최대 293까지)

unknown 시그널들은 청사진 따고 문자열 내보내기 하면 사라지는 버그가 있어서 주의해야 함