두구두구당당 둥당~~ 드디어 함수를 배우기 시작했습니다~~~~~
좀~~~더~~~~ 멋~~~있~~~어~~~보~~이~~게~~~ 코드를 짤 수 있게 되었다!
가독성은 덤! 코드재사용이 용이해진 것도 덤!!
그래서 일단 함수는 대강 프로그래밍에 관심이 있다면 형태정도는 봤을 것이다.
function 함수명(파라미터){
블라블라~~~
}
요런 형태!
파라미터도 받을 수도 있고 아닐 수 도있고 return을 해주기도 안해주기도 한다.
설계자 마음대로 만들 수 있다. 물론 제대로 작동해야겠지만....
솔직히 함수에 대해서 검색해보고 여러 블로그글들을 봤을 때 어떤건 파라미터를 받기도 return을 받기도 아니기도 해서 어떻게 써야하는지 너무 어려웠었는데 직접 써보고 나니까 왜 사용하는지 이해가 갔다.
과제를 하는데 주 ---- 욱 코드를 썼더니 변수하나 고치거나 할때마다 전부다 찾아서 일일이 고쳐야하니 눈알이 빠질 것 같다... 만약 제대로 안고쳐지면 오타가 나거나 한것도 아니라 결과값은 C망인데 오류라고 알려주지도 않는다ㅠㅠㅠㅠ
함수는 프로그래머가 이모저모 써보면서 어떤 기능을 함수로 만들어서 코드에서 활용할 것인지 잘 설계를 해야할 것같다. 개인적으로 함수를 쓰면 왠지 멋있어보인다ㅎ
여튼 오늘은 고차함수의 정의와 함께 배열에 대해서 좀 더 배웠다. 물론 과제도!^^!!!!
오늘 배운 개념들과 예시코드 ㄱㄱ
그래서 고차함수가 무어냐
고차함수
함수를 인수로 전달받거나 함수를 반환하는 함수. 고차 함수는 외부상태의 변경이나 가변데이터를 피하고 불변성을 지향하는 함수형 프로그래밍에 기반을 두고 있다.
라고 한다.
오호... 함수를 인수로 받을 수 있다니 언젠가 요긴하게 쓸 것 같은 느낌....!!
sort
원본배열을 정돈해서 오름차순으로 리턴해준다. 원본 배열을 직접 건드림!!
const fruit = [2, 3, 5 ,1, 4];
fruit.sort();
이렇게 사용하면 된다.
sort로 정렬하고 나면 모두가 예상할 수 있듯이
fruit = [ 1, 2, 3, 4, 5] 이렇게 정렬이 될 것이다.
물론 문자도 된다! 한글도!!! 유니코드 포인트를 기준으로 순서를 정렬해주기 때문이다.
그. 런. 데
const point = [46, 3, 22, 15, 40, 55];
point.sort();
console.log(point);
\요렇게 사용하면 어떨까? 우리의 기대 결과는
3, 15, 22, 40, 46, 55 이렇게 나오는 것이다.
두구두구 두구닥닥
띠요옹 오름차순으로 제대로 정렬이 안된다. 왜!!! 제대로 일을 안해!!! 라고 화가 날 수 있겠지만
아니다 제대로 일한게 맞다....!
sort 메서드는 <유니코드>를 기준으로 정렬하기 때문에 저 순서가 맞다.
궁금할 누군가를 위해 저 순서대로 유니코드 값을 적어놓는다
=================================
15 : U+0031U+0035
22 : U+0032U+0032
3 : U+0033
40 : U+0034U+0030
46 : U+0034U+0036
55 : U+0035U+0035
==================================
만약 숫자를 오름차순으로 정렬해주고 싶다면, 오름차순으로 정렬하는 함수를 만든다음 sort메서드에 파라미터로 주면 된다. sort(정렬함수());
(sort 에 직접 정리규칙을 넣어줘야한다.)
물론 직접 for문을 돌려도 되긴한다ㅎㅎ
reverse
배열의 요소들을 내림차순으로 정렬해준다
사용방법은 sort와 같다
arr.reverse(); 요렇게! 물론 sort처럼 유니코드를 기반으로 정렬해주기 때문에 숫자를 정렬하고 싶다면 규칙을 직접 지정해줘야한다.
그 다음은
화살표 함수
전통적인 함수표현이라고 한다. 코드가 짧아지지만 단점으로는 break와 continue를 쓸 수 없다.
반복문이 조건에 의해 끝나기 전까지 끝낼 수 없다.
아... 이건 줄여서 쓰는 표현을 나도 잘 못쓰겠다ㅠ.... 그리고 아직 예외처리를 하는 방법을 몰라서 for문안에 조건문을 써주는 방식으로 걸러내는 중이라 쓴적이 없다ㅋㅋㅋㅋ
여튼 사용 방법은 다음과 같다.
let sum = function(a,b){
return a+b;
}
// 오른쪽에 있는 식을 평가하고 리턴한다(오른쪽의 결과를 리턴).
// 왼쪽이 파라미터를 의미
let sum1=(a,b)=>a+b;
let double = n=>n*2;
let print = ()=>alert('안녕');
이런식으로 쓰인다고 하는데.... 난 잘 모르겠다...ㅎㅎ
그리고
재귀함수
자기자신을 호출한다. 함수가 자기 자신을 다시 호출한다.
종료조건이 반드시 있어야 한다.
음.......
흐으음......
ㅋㅋㅋㅋㅋ음 내가 느끼기엔 반복문과 비슷한 느낌인데 함수이고.... 그리고 함수내용안에 자기 자신을 호출하도록 했다니.... 그냥 듣기엔 이해가 안가서 교수님이 주신 예시를 갖고왔다.
//피보나치 수열
function fibo(num){
let res = [0,1];
if(num==0){
console.log([0]);
}
if(num==1){
console.log([0,1]);
}
for(let i= 2; i<=num; i++){
res.push(res[i-2]+res[i-1]);
console.log(res);
}
}
fibo(8);
피보나치 수열을 코드로 구현한 것이다
<재귀함수>
function RecursiveFunction(n){
if(n<=1)return 1; //종료조건
return n+RecursiveFunction(n-1);
}
function RecursiveFibo(){
if(num<2){
return num;
}
return RecursiveFibo(num-1)+RecursiveFibo(num-2);
}
console.log(RecursiveFibo(8));
ㅇ...오호.... return에 자기자신을 호출하고 있으니 재귀함수가 맞는 것 같다.
음.....흐으음..... 보통 어떤 상황에 쓰일지는 모르겠으나
보통 일반적인 경우에 속도가 for문보다 느리다고 하니 잘 쓰지 않을 것 같다ㅎㅎㅎ....
자 이제 배운 것 들을 바탕으로 실습을 해보자!☆
실습문제!
숫자 야구게임 만들기
조건
================================================================================
<처참한 시도-1>
/*
실습과제
숫자야구게임만들기
1. 컴퓨터는 임의의 숫자 3개를 낸다.
2. 유저는 아무거나 낼 수 있다.
ex) 컴 1 2 3
유저 7 8 9
=> 아웃
====================
4 5 6
5 7 9 1볼(숫자는 하나 같고 자리가 틀림)
===========================
1,2,3
1,2,4 => 2스트라이크(숫자 2개맞고 자리도 동일)
======================================
- 같은숫자 같은 인덱스값 = > 스트라이크
- 3스트라이크면 =>홈런 승리
- 플레이 기회는 자유
*/
//컴퓨터가 내는 공 번호가 담긴 배열
let com_ball = [];
// 컴퓨터가 공으로뽑은 번호
let ball = 0;
//유저가 내는 공을 받을 배열
let user_ball = [];
//유저가 낸 공번호
let set_ball = 0;
let count = 1;
// 컴퓨터의 처음뽑은 수는 변하지 않는다 user_ball의 중복검사를 위해 객체로 담아줄 것 let user_shoot = 0; let
// set_ball=0; com이 1~9사이에서 중복되지 않게 임의의 숫자 3개를 뽑는다
for (let i = 1; i <= 3; i++) {
ball = Math.floor((Math.random() * 8) + 1); //1~9사이의 숫자 뽑기
// include는 '===' 연산자를 사용함
if (com_ball.indexOf(ball) == -1) {
com_ball.push(ball);
} else if (com_ball.indexOf(ball) != -1) {
i--;
}
}
console.log("컴퓨터가 고른 공 :" + com_ball);
// ////////객체 배열로 변환//////////////
// 공을 3개 내게 한다. 중복되지 않은 숫자로 내게 검사한다.
alert("숫자 야구게임을 시작합니다.\n *총 3번 입력합니다.* ");
while ((count <= 1) && (check_strike != 3)) {
alert(count + " 번 째 게임을 시작합니다.")
while (true) {
for (let i = 0; i < 3; i++) {
alert(i + 1 + " 번 째 공을 던집니다. ")
set_ball = Number(prompt("1~9사이의 숫자를 입력하세요 : \n ** 주의 같은 숫자는 입력하면 안됩니다.**"));
if (user_ball.indexOf(set_ball) == -1) {
user_ball.push(set_ball);
if (user_ball.length == 3) { // 중복된 숫자 없이 공을 3개 잘 냈으면 끝
alert("공을 3개 다 던지셨습니다.\n 승패를 확인합니다.")
break;
}
alert(set_ball + "번 공을 던지셨습니다.\n 다음 공을 입력해주세요");
} else if (user_ball.indexOf(set_ball) != -1) {
alert("중복된 숫자는 입력할 수 없습니다.\n 다시 입력해주세요.");
i--;
continue;
}
}
break;
}
// 두 배열 비교해서 볼. 스트라이크 검사 com_ball -컴퓨터 볼 user_ball- 유저볼 const winner = number;
// 스트라이크 갯수 계산
let strike = [];
strike = com_ball.concat(user_ball);
let check_strike = new Set(strike);
// console.log("set으로 바꿔줌" + check_strike);
//console.log("set으로 바꿔줌" + typeof(check_strike));
//set은 배열로 인식이 안된다. 배열로 다시 바꿔줘야함
check_strike = Array.from(check_strike);
//console.log("배열로 바꿔줌" + check_strike);
//console.log(check_strike);
//console.log("배열로 바꿔줌" + typeof(check_strike));
//console.log("스트라이크 개수 : " + (6 - check_strike.length));
// 스트라이크인 공만 제거한 배열 재생성 strike에서 두번이상 나온값을 찾아서 -> 이걸 제거한 각각 com_ball/ user_ball
// 배열을 새로 만들고 각각 값비교 ball++
let check_ball = 0;
// 스트라이크인
for (let j = 0; j < 3; j++) {
for (let k = 0; k < 3; k++) {
//com의 0번째 인덱스와 같은 값이 있으면 인덱스가 같은건지 비교
if (com_ball[j] == user_ball[k]) {
if (com_ball.indexOf(com_ball[j]) != user_ball.indexOf(user_ball[k])) {
check_ball++;
}
}
}
}
//볼 개수 계산 컴퓨터와 유저가 같은값을 뽑았으면 그걸 제거하고 남은 배열로 볼이 몇개인지 비교
alert(count + " 번째 게임 결과 발표!!!! \n 스트라이크 갯수 : " + (
6 - check_strike.length
) + "\n 볼의 갯수 : " + check_ball);
alert(count + " 번째 게임에서 \n 내가 낸 공의 번호 : " + user_ball);
console.log("이번판 유저가 낸 공 번호 : " + user_ball);
console.log("이번판 볼 갯수 : " + check_ball);
console.log("이번판 스트라이크 갯수 : " + check_strike);
count++;
}
ㅋㅋㅋㅋㅋㅋㅋ값을 제대로 안찍어내서 어떤 구간에서 걸리는지 찾기위해 사용한 무분별한 console.log들....
컴퓨터의 공을 랜덤으로 뽑아서 배열로 담아줬다. 그리고 두번째 세번째가 먼저번의 공들과 중복이 되지 않도록 indexOf로 중복검사를 해주면서 넣었다.
유저의 공은 prompt로 입력받아서 number 형태로 바꿔준 후 컴퓨터의 공과 같은 방법으로 배열에 담아주었다
랜덤함수로 공을 뽑아준 다음에 set으로 중복검사를 한 다음 다시 배열과 인덱스 별 값 비교를 하려니 에러가 났다.
객체에 대한 개념이 모호했는데 이때의 뻘짓으로 배열도 객체의 범위 안에 들어간다는걸 알게됐다....ㅠ
배열은 각 인덱스 별로 같은 타입의 데이터들이 담겨있는 형태이며 인덱스마다 값이 1개씩 들어있으니 당연히 값비교를 하려면 같은 형태의 데이터 형태여야 비교가 가능했던것....!
그래서 Array.from() 으로 set()을 통해 배열 형태가 아닌 객체를 배열형태로 만들어줬다.
그러니까 배열을 => 배열이 아닌객체로 만들어서 중복검사 후 => 다시 배열로 만들기ㅋㅋㅋㅋㅋ
그리고 만약 중복된 숫자가 있어서 제거되면 또 숫자를 랜덤하게 뽑고 중복검사를 하고 반복을 하는것이다...ㅋㅋㅋㅋㅋ
일을 만들어서 해버린것..... 지금보니 매우매우매우매우 비효율적이다...
중복검사를 해주는 메서드가 있다고 해서 사용해보려고 신나서 써본건데....흨흨....
그래서 결국 갈아엎었다. 반복문을 사용하든 어떻든 굉장히 길어지기 때무네..... 완성코드는 과제 카테고리에 올려두었다...! 혹시 궁금하다면 과제란으로 가보시길!
'블록체인기반 SW 개발자 과정(feat.경일게임아카데미)' 카테고리의 다른 글
<JAVASCRIPT> 22.06.02일 자 기록 // 콜백함수 (callback ) / 익명함수 / Promise() (0) | 2022.06.03 |
---|---|
<JAVASCRIPT> 22.05.27일자 기록 / 객체(Object) / 객체의 특정 값을 뽑아오기. (0) | 2022.06.02 |
<JAVASCRIPT> 22.05.24일 7일차 기록 / for 반복문 / 삼각형 찍기 (0) | 2022.05.24 |
<JAVASCRIPT> 22.05.23일 6일차 기록 / 자바스크립트의 기본, 연산자 / switch 조건문 형식 (0) | 2022.05.23 |
<JAVASCRIPT> 22.05.20 5일차 기록 / 자바스크립트의 기본 / 자바스크립트의 자료형 (0) | 2022.05.20 |